思路:一个O(n)O(n)的做法。我们发现b_1,b_2,...,b_xb1,b2,...,bx都加11就相当于b_{x+1},b_{x+2},...,b_nbx+1,bx+2,...,bn都减11。然后我们可以倒着做,记一下最大值,如果遇到了修改操作,就把最大值减11,然后判断一下这个人会不会被消灭掉,然后再更新一下最大值。
1 #define cn(i,p,q) for(int i=p;i<=q;i++) 2 #define cn1(i,p,q) for(int i=p;i>=q;i--) 3 #define pr(x) printf("%d ",x) 4 #define prr(x) printf("%d",x) 5 #define prrr(x) printf(" %d",x) 6 #define sc(x) scanf("%d",&x) 7 #define scc(x) scanf("%lf",&x) 8 #define pr1(x) printf("%.2f ",x) 9 #include<stdio.h> 10 #include<algorithm> 11 #include<iostream> 12 #include<string.h> 13 #include<stdlib.h> 14 #include<math.h> 15 int maxx[2][1];//两种情况分别表示两个不同队中从后往前时最大值 16 typedef struct pp 17 { 18 int xx; 19 int yy; 20 int flag; 21 } ss; 22 const int N=1e6+10; 23 ss a[N]; 24 int b[N];//记录在何时放技能的次数 25 26 using namespace std; 27 int main(void) 28 { 29 int n,m,l,k,s; 30 sc(n); 31 int x; 32 int y; 33 while(n--) 34 { 35 sc(x); 36 sc(y); 37 memset(b,0,sizeof(b)); 38 memset(maxx,0,sizeof(maxx)); 39 int qq=0; 40 cn(i,1,x) 41 { 42 int vp; 43 int va; 44 sc(vp); 45 sc(va); 46 a[i].xx=vp; 47 a[i].yy=va; 48 a[i].flag=0; 49 } 50 cn(i,1,y) 51 { 52 sc(k); 53 b[k]++; 54 } 55 maxx[a[x].xx][0]=a[x].yy;//最后一个先初始化最大 56 cn1(i,x-1,1) 57 { 58 cn(j,0,1) 59 { 60 maxx[j][0]-=b[i];//减放技能所减少的 61 } 62 int zz=(a[i].xx+1)%2; 63 if(a[i].yy<maxx[zz][0]) 64 { 65 qq++; 66 }//如果当前的小于另一组的最大值这个点就会消失 67 maxx[a[i].xx][0]=max(maxx[a[i].xx][0],a[i].yy);//更新同一组的最大值 68 69 } 70 int zk=x-qq; 71 pr(zk); 72 } 73 return 0; 74 }