[BZOJ2827]千山鸟飞绝
1 #include <cmath> 2 #include <ctime> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <iostream> 7 #include <algorithm> 8 # define maxn 30010 9 using namespace std; 10 void ot(int x){cout<<"***** ->"<<x<<endl;} 11 int n,m; 12 int bd[maxn]; 13 int ans1[maxn],ans2[maxn]; //ans2==num 14 struct ROU{ 15 int val,id; 16 }; 17 bool operator < (const ROU a,const ROU b){ 18 if(a.val==b.val) return a.id<b.id; 19 return a.val<b.val; 20 } 21 struct Treap{ 22 Treap* ch[2]; 23 ROU tt; 24 int size,key,mk1,mk2; 25 Treap(int v,int ii) 26 {size=1; tt.val=v; tt.id=ii; key=rand(); mk1=mk2=0; ch[0]=ch[1]=NULL;} 27 void update() 28 {size=1+(ch[0]?ch[0]->size:0)+(ch[1]?ch[1]->size:0);} 29 }; 30 typedef pair<Treap*,Treap*> D; 31 int Size(Treap* now){return now? now->size:0;} 32 int mmxx(Treap *now){return now? now->tt.val:0;} 33 void pushdown(Treap* &now){ 34 if(!now) return; 35 if(now->ch[0]){ 36 now->ch[0]->mk1=max(now->mk1,now->ch[0]->mk1); 37 now->ch[0]->mk2=max(now->mk2,now->ch[0]->mk2); 38 } 39 if(now->ch[1]){ 40 now->ch[1]->mk1=max(now->mk1,now->ch[1]->mk1); 41 now->ch[1]->mk2=max(now->mk2,now->ch[1]->mk2); 42 } 43 int ii=now->tt.id; 44 ans1[ii]=max(ans1[ii],now->mk1); 45 ans2[ii]=max(ans2[ii],now->mk2); 46 now->mk1=0; now->mk2=0; 47 } 48 D Split(Treap* now,int k){ 49 if(!now) return D(NULL,NULL); 50 D y; 51 pushdown(now); 52 if(Size(now->ch[0])>=k) 53 {y=Split(now->ch[0],k); now->ch[0]=y.second; now->update(); y.second=now;} 54 else 55 {y=Split(now->ch[1],k-Size(now->ch[0])-1); now->ch[1]=y.first; now->update(); y.first=now;} 56 return y; 57 } 58 Treap* Merge(Treap* a,Treap* b){ 59 if(!a) return b; 60 if(!b) return a; 61 if(a->key < b->key) 62 {a->ch[1]=Merge(a->ch[1],b); a->update(); return a;} 63 else 64 {b->ch[0]=Merge(a,b->ch[0]); b->update(); return b;} 65 } 66 int Getkth(Treap* now,ROU o){ 67 if(!now) return 0; 68 return (!(now->tt<o))? Getkth(now->ch[0],o):Getkth(now->ch[1],o)+Size(now->ch[0])+1; 69 } 70 int Findkth(Treap* &rt,int k){ 71 D x=Split(rt,k-1); 72 D y=Split(x.second,1); 73 Treap* ans=y.first; 74 rt=Merge(Merge(x.first,ans),y.second); 75 return ans? ans->tt.val:0; 76 } 77 void add_mk(ROU o,Treap* &now){ 78 if(!now) return ; 79 int da=Findkth(now,now->size); 80 now->mk1=max(now->mk1,o.val); 81 now->mk2=max(now->mk2,now->size); 82 ans1[o.id]=max(ans1[o.id],da); 83 ans2[o.id]=max(ans2[o.id],now->size); 84 } 85 void Insert(ROU o,Treap* &rt){ 86 add_mk(o,rt); 87 int k=Getkth(rt,o); 88 D x=Split(rt,k); 89 Treap* now=new Treap(o.val,o.id); 90 rt=Merge(Merge(x.first,now),x.second); 91 } 92 void Delete(ROU o,Treap* &rt){ 93 int k=Getkth(rt,o); 94 D x=Split(rt,k); 95 D y=Split(x.second,1); 96 int ii=y.first->tt.id; 97 ans1[ii]=max(ans1[ii],y.first->mk1); 98 ans2[ii]=max(ans2[ii],y.first->mk2); 99 rt=Merge(x.first,y.second); 100 } 101 struct HHs{ 102 struct node{ 103 int x,y,nxt; 104 Treap* rt; 105 }g[4000000]; 106 int e,adj[80000]; 107 int modx; 108 int mody; 109 int mod; 110 HHs(){ 111 memset(adj,-1,sizeof(adj)); 112 modx=7307; mody=9991; mod=76543; 113 } 114 void add(int now,int x,int y){ 115 g[e].x=x; g[e].y=y; g[e].nxt=adj[now]; 116 adj[now]=e++; 117 } 118 int find(int x,int y){ 119 int now=(((x%modx)+modx)%modx)*(((y%mody)+mody)%mody)%mod; 120 for(int i=adj[now];i!=-1;i=g[i].nxt){ 121 if(x==g[i].x && y==g[i].y){ 122 return i; 123 } 124 } 125 add(now,x,y); return e-1; 126 } 127 }hs; 128 int pos[maxn][3]; 129 void init(){ 130 scanf("%d",&n); 131 int now; ROU o; 132 for(int i=1;i<=n;i++){ 133 scanf("%d%d%d",&bd[i],&pos[i][0],&pos[i][1]); 134 now=hs.find(pos[i][0],pos[i][1]); 135 o.id=i; o.val=bd[i]; 136 Insert(o,hs.g[now].rt); 137 } 138 } 139 void work(){ 140 scanf("%d",&m); 141 int iid,x,y; 142 int now; ROU o; 143 for(int i=1;i<=m;i++){ 144 scanf("%d%d%d",&iid,&x,&y); 145 o.id=iid; o.val=bd[iid]; 146 now=hs.find(pos[iid][0],pos[iid][1]); 147 Delete(o,hs.g[now].rt); 148 pos[iid][0]=x; pos[iid][1]=y; 149 now=hs.find(x,y); 150 Insert(o,hs.g[now].rt); 151 } 152 for(int i=1;i<=n;i++){ 153 now=hs.find(pos[i][0],pos[i][1]); 154 o.id=i; o.val=bd[i]; 155 Delete(o,hs.g[now].rt); 156 } 157 long long ans; 158 for(int i=1;i<=n;i++){ 159 ans=(long long)ans1[i]*ans2[i]; 160 printf("%lld\n",ans); 161 } 162 } 163 int main(){ 164 // freopen("a.in","r",stdin); 165 init(); 166 work(); 167 }