BZOJ2274: [Usaco2011 Feb]Generic Cow Protests
n<=100000个数,求划分为若干和不小于0的区间的方案数%1000000009。
注意模数啊啊啊。。f(i)--前i个数方案数,
n2过不了。不过上面那个东西就是找满足sum(i)>=sum(j)的f,随便线段树合并或者平衡树想必都可以写啦
然而splay写炸了。。求和最后一步旋转转错了。。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<algorithm> 5 //#include<iostream> 6 using namespace std; 7 8 int n; 9 #define maxn 100011 10 int a[maxn],sum[maxn]; 11 const int mod=1000000009; 12 struct Splay 13 { 14 struct Node 15 { 16 int id,v; 17 int sum; 18 int son[2],fa; 19 }a[maxn]; 20 int size,root; 21 Splay() {size=root=0;} 22 void up(int x) 23 { 24 if (!x) return; 25 const int &p=a[x].son[0],&q=a[x].son[1]; 26 a[x].sum=((a[p].sum+a[q].sum)%mod+a[x].v)%mod; 27 } 28 void rotate(int x) 29 { 30 const int y=a[x].fa,z=a[y].fa; 31 bool w=(x==a[y].son[0]); 32 a[x].fa=z; 33 if (z) a[z].son[y==a[z].son[1]]=x; 34 a[y].son[w^1]=a[x].son[w]; 35 if (a[x].son[w]) a[a[x].son[w]].fa=y; 36 a[y].fa=x; 37 a[x].son[w]=y; 38 up(y);up(z); 39 } 40 void splay(int x) 41 { 42 while (a[x].fa) 43 { 44 const int y=a[x].fa,z=a[y].fa; 45 if (z) 46 { 47 if ((x==a[y].son[0])^(y==a[z].son[0])) rotate(x); 48 else rotate(y); 49 } 50 rotate(x); 51 } 52 up(x);root=x; 53 } 54 void insert(int v,int id) 55 { 56 if (!root) 57 { 58 root=++size; 59 Node &now=a[size]; 60 now.v=v;now.id=id;now.sum=v; 61 now.son[0]=now.son[1]=now.fa=0; 62 } 63 else 64 { 65 int x=root,last=0,from; 66 while (x) 67 { 68 last=x; 69 if (a[x].id<=id) x=a[x].son[from=1]; 70 else x=a[x].son[from=0]; 71 } 72 size++;Node &now=a[size]; 73 now.v=v;now.id=id;now.sum=v; 74 now.son[0]=now.son[1]=0;now.fa=last; 75 a[last].son[from]=size; 76 up(last); 77 splay(size); 78 } 79 } 80 int find(int id) 81 { 82 int x=root,ans=0; 83 while (x) 84 { 85 if (a[x].id<=id) ans=x,x=a[x].son[1]; 86 else x=a[x].son[0]; 87 } 88 if (ans) splay(ans); 89 return ans; 90 } 91 int sum(int id) 92 { 93 int x=find(id); 94 if (!x) return 0; 95 if (a[x].son[1]) 96 { 97 int y=a[x].son[1]; 98 while (a[y].son[0]) y=a[y].son[0]; 99 splay(y); 100 return a[a[y].son[0]].sum; 101 } 102 else return a[x].sum; 103 } 104 }t; 105 int f[maxn]; 106 int main() 107 { 108 scanf("%d",&n); 109 for (int i=1;i<=n;i++) scanf("%d",&a[i]); 110 sum[0]=0;for (int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i]; 111 f[0]=1;t.insert(f[0],0); 112 for (int i=1;i<=n;i++) 113 { 114 f[i]=t.sum(sum[i]); 115 t.insert(f[i],sum[i]); 116 } 117 printf("%d\n",f[n]); 118 return 0; 119 }