题意:长度为n的Chocolate,为n份1,2,3...n,每操作一次假如是[i,j],则i到j的(包括i, 和j)被买完。
要求输出每次操作能买的Chocolate有多少份。
例如;
6 4
1 2//可以买1,2 两份。
4 4//可以买4一份。
1 3//因为1,2已经买过了,只剩下3了,所以只能买3一份。
1 4//1,2,3,4都买过了。所以输出0。
#include#include const int maxn = 10000001;int find[maxn];//find[i]存储的是前一步指向的。int cal(int i){ return i==find[i] ? i : find[i] = cal(find[i]);//并查集}void nextcal(int i, int j)//小的指向大的{ int x = cal(i); int y = cal(j); if (x != y) { if (x > y) { find[y] = x; } else { find[x] = y; } }}int main(void){ int t, n, m; int a, b, i; int res; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (i=1; i<=n+1; i++) { find[i] = i; } while (m--) { res = 0; scanf("%d%d", &a, &b); for (i=a; i<=b;) { if ( i== find[i]) { //printf("cal(%d)==%d, find[%d]==%d\n",i, cal(i), i, find[i]); res++; nextcal(i, b+1); //printf("cal(%d)==%d, find[%d]==%d\n",i, cal(i), i, find[i]); i++; } else { //printf("cal(%d)==%d, find[%d]==%d\n",i, cal(i), i, find[i]); i = cal(i);//关键优化,注意不是find[i]; } } printf("%d\n", res); } } return 0;}