cf D. Vessels
http://codeforces.com/contest/371/problem/D
第一遍写的超时了,然后看了别人的代码,思路都是找一个点的根,在往里面加水的时候碗中的水满的时候建立联系。查询的时候直接查询就行。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define LL __int64 5 #define maxn 500000 6 using namespace std; 7 8 int f[maxn]; 9 LL a[maxn],cap[maxn]; 10 11 int find1(int x) 12 { 13 if(f[x]==x) 14 { 15 return x; 16 } 17 return f[x]=find1(f[x]); 18 } 19 20 void deal(int pos,LL y) 21 { 22 while(y>0) 23 { 24 int c=find1(pos); 25 a[c]+=y; 26 y=a[c]-cap[c]; 27 if(y<=0) return; 28 a[c]=cap[c]; 29 if(a[c]==cap[c]) f[c]=f[c+1]; 30 } 31 } 32 33 int main() 34 { 35 int n; 36 scanf("%d",&n); 37 for(int i=1; i<=n; i++) 38 { 39 scanf("%I64d",&cap[i]); 40 f[i]=i; 41 } 42 f[n+1]=n+1; 43 cap[n+1]=200000000000000LL; 44 int m; 45 scanf("%d",&m); 46 while(m--) 47 { 48 int xx,p; 49 LL x; 50 scanf("%d",&xx); 51 if(xx==1) 52 { 53 scanf("%d%I64d",&p,&x); 54 deal(p,x); 55 } 56 else 57 { 58 scanf("%d\n",&p); 59 printf("%I64d\n",a[p]); 60 } 61 } 62 return 0; 63 }