题解:
对于新插入的线段,查询有多少个线段左端点大于等于该线段的左端点。 再查询有多少个线段的右端点大于该线段右端点, 两者之差就是答案。
这里注意两个问题,一个是离散化,第二个这道题时间卡的可能比较严,线段树貌似会超时~
好久没写离散化了。。。生疏了
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1000005; int n; //---------------------------------------------------------- int Hash[maxn * 2]; int Hash_num; int HASH(int u){ return lower_bound(Hash + 1,Hash + Hash_num,u) - Hash; } void Hash_debug(){ for(int i = 1; i < Hash_num; i++) printf("%d ",Hash[i]); puts(""); } //----------------------------------------------------------- int C[2][maxn]; int lowbit(int x){ return x & (-x); } int sum(int op,int x){ int ret = 0; while(x > 0){ ret += C[op][x]; x -= lowbit(x); } return ret; } void add(int op,int x,int value){ while(x <= Hash_num){ C[op][x] += value; x += lowbit(x); } } //----------------------------------------------------------- struct Input{ int op,id,lv; }input[maxn]; int pid[maxn]; //------------------------------------------------------------ int main(){ int Case = 1; while(scanf("%d",&n) != EOF){ int cnt = 1; Hash_num = 1; Hash[Hash_num++] = 0; memset(C,0,sizeof(C)); for(int i = 0; i < n; i++){ scanf("%d%d",&input[i].op,&input[i].lv); if(input[i].op == 0){ input[i].lv ++; Hash[Hash_num++] = input[i].lv; Hash[Hash_num++] = input[i].lv + cnt; pid[cnt] = i; input[i].id = cnt ++; } } sort(Hash + 1,Hash + Hash_num); Hash_num = unique(Hash + 1,Hash + Hash_num) - Hash; //Hash_debug(); printf("Case #%d:\n",Case++); for(int i = 0; i < n; i++){ if(input[i].op == 0){ int sum1 = sum(0,Hash_num); int sum2 = sum(1,Hash_num); int lv = HASH(input[i].lv); int rv = HASH(input[i].lv + input[i].id); int sum11 = sum1 - sum(0,lv - 1); int sum22 = sum2 - sum(1,rv); printf("%d\n",abs(sum11 - sum22)); add(0,lv,1); add(1,rv,1); } else{ int id = pid[input[i].lv]; int lv = HASH(input[id].lv); int rv = HASH(input[id].lv + input[id].id); add(0,lv,-1); add(1,rv,-1); } } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-24 02:32:34