题目链接
思路:
带权并查集维护 + 离散化,当l~r区间1的个数为odd奇数时可以看成((d[r] - d[l-1])%2)==1,当l~r区间1的个数为even偶数时可以看成((d[r] - d[l-1])%2)==0,然后所有的数据还要加个离散化就差不多了,找出第一个与前面相悖的答案break即可。
开始把n看成一个数了卡了半天,后面思路对了又因为if判断中的多项表达式的符号优先级wa了好多发,以后if中的多项表示还是全加括号的好。
代码:
#include#include #include #include #include #include #include #include #include #include #include #include #define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL) #define debug(a) cout << "debug : " << (#a) << " = " << a << endl using namespace std; typedef long long ll; typedef pair PII; const int N = 1e4 + 10; const int INF = 0x3f3f3f3f; const double eps = 1e-6; const int mod = 998244353; int n, m; int f[N], d[N]; vector alls; struct node { int x, y; char op[10]; } a[5100]; int find(int x) { if (f[x] != x) { int u = find(f[x]); d[x] += d[f[x]]; f[x] = u; } return f[x]; } int main() { cin >> n >> m; for (int i = 1; i <= m; i++) { scanf("%d%d%s", &a[i].x, &a[i].y, a[i].op); a[i].x--; alls.push_back(a[i].x), alls.push_back(a[i].y); } sort(alls.begin(), alls.end()); alls.erase(unique(alls.begin(), alls.end()), alls.end()); for (int i = 1; i <= m; i++) { int x = lower_bound(alls.begin(), alls.end(), a[i].x) - alls.begin(); int y = lower_bound(alls.begin(), alls.end(), a[i].y) - alls.begin(); f[x] = x, f[y] = y, d[x] = 0, d[y] = 0; } int ans = m; for (int i = 1; i <= m; i++) { int x = lower_bound(alls.begin(), alls.end(), a[i].x) - alls.begin(); int y = lower_bound(alls.begin(), alls.end(), a[i].y) - alls.begin(); string op = a[i].op; int f1 = find(x), f2 = find(y); if (f1 != f2) { f[f1] = f2; if (op[0] == 'o') d[f1] = d[y] + 1 - d[x]; else d[f1] = d[y] - d[x]; while (d[f1] < 0) d[f1] += 2; } else { if (op[0] == 'o') { if (((d[x] - d[y]) % 2) == 0) ans = i - 1; } else { if ((d[x] - d[y]) % 2) ans = i - 1; } } if (ans != m) break; } printf("%dn", ans); return 0; }



