并查集做,满了的水池合并为为最后一个为父节点
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#define maxn 200010
int n;
int next[maxn];
int v[maxn];
int lft[maxn];
/*
union-find
somewhere change to your need
*/
void GxdUnionFindInit(int* gnum,int glen)
{
for(int i=0;i<glen;i++) gnum[i]=i;
}
int GxdUnionFindSearch(int* gnum,int glen,int gkey)
{
int key = gkey;
while(key!=next[key]) key = next[key];
int fa = key;
//path compress
key = gkey;
while(key!=fa)
{
next[key] = fa;
key = next[key];
}
return fa;
}
void GxdUnionFindAdd(int* gnum,int glen,int ga,int gb)
{
int faa = GxdUnionFindSearch(gnum,glen,ga);
int fab = GxdUnionFindSearch(gnum,glen,gb);
if(faa==fab) return ;
//here is a change to your need
//the father is always bigger than the child here.
next[std::min(faa,fab)] = std::max(faa,fab);
}
int main()
{
memset(lft,0,sizeof(lft[0]));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
lft[i] = v[i];
}
GxdUnionFindInit(next,n+1);
int m;
scanf("%d",&m);
while(m--)
{
int t;
scanf("%d",&t);
if(t==1)
{
int p,x;
scanf("%d%d",&x,&p);
int last = x;
x=next[x];
while(p>=lft[x]&&x!=n)
{
p-=lft[x];
lft[x] = 0;
GxdUnionFindAdd(next,n+1,x,x+1);
x = next[x];
}
lft[x]=std::max(lft[x]-p,0);
GxdUnionFindAdd(next,n+1,last,x);
}else
{
int k;
scanf("%d",&k);
if(lft[k]==0) printf("%d\n",v[k]);
else printf("%d\n",v[k]-lft[k]);
}
}
return 0;
}