1. 程式人生 > >cogs 516【求和】【解題報告】

cogs 516【求和】【解題報告】

%d col i+1 前驅 its pen 整數 插入 nbsp

516. 求和

【問題描述】

給出一個數列A1,A2….,An和K,P。
設Sij=Ai+Ai+1+…+Aj
Anaswer=min{Si,j mod P | si,j mod P≥K),其中i≤j,(si,j mod P | si,j mod P≥K}非空。

【輸入格式】
第一行一個正整數n,K,P。
第二行n個整數,表示一個數列A1,A2,…,An

【輸出格式】
在第一行輸出Answer。

【輸入樣例】
7 2 17
12
13
15
11
16
26
11

【輸出樣例】

2

【數據範圍】
在100%的數據中,1<n<100000,1<K,P,ai<10^8,i=1,2…n

treap的題目

求出前綴和,一邊求一邊取膜,每一次插入一個前綴和x,插入之前去查找一個值y,使(x-y)%p>=k,我們分兩種情況來討論,x>=y和x<y,當x>=y時x-y是一個正數,我們直接在平衡樹

中查找x-k的前驅,x-y即為所求值,取min;對於x<y,因為a全是正數,所以x取膜前一定比y取膜前大,那麽我們可以對x+p,再-y,得到的即為當y>x時這一段取膜後的值,同樣查找x+p-k的前驅。如果x+p-k查到的y<=x怎麽辦?其實不用管,因為他肯定不會比x-k查完之後求得的值更優。

技術分享圖片
 1 #include<bits/stdc++.h>
 2
using namespace std; 3 const int inf=100005; 4 struct treap{ 5 int rnd; 6 int l,r; 7 int v; 8 int siz; 9 int w; 10 }t[inf]; 11 void update(int x){ 12 t[x].siz=t[t[x].l].siz+t[t[x].r].siz+t[x].w; 13 } 14 void lrot(int &x){ 15 int k=t[x].r; 16 t[x].r=t[k].l;
17 t[k].l=x; 18 update(x); 19 update(k); 20 x=k; 21 } 22 void rrot(int &x){ 23 int k=t[x].l; 24 t[x].l=t[k].r; 25 t[k].r=x; 26 update(x); 27 update(k); 28 x=k; 29 } 30 int rt,sz; 31 int a[inf],n,k,p,mi=0x7fffffff; 32 int Rand(){ 33 return ((rand()<<12)+rand())%20021031; 34 } 35 void insert(int &x,int v){ 36 if(!x){ 37 x=++sz; 38 t[x].rnd=Rand(); 39 t[x].v=v; 40 t[x].siz=t[x].w=1; 41 return ; 42 } 43 t[x].siz++; 44 if(t[x].v==v){ 45 t[x].w++; 46 return ; 47 } 48 if(v<t[x].v){ 49 insert(t[x].l,v); 50 if(t[t[x].l].rnd<t[x].rnd)rrot(x); 51 } 52 else { 53 insert(t[x].r,v); 54 if(t[t[x].r].rnd<t[x].rnd)lrot(x); 55 } 56 } 57 int pre(int x,int v,int Max){ 58 if(!x)return Max; 59 if(t[x].v>v)return pre(t[x].l,v,Max); 60 else return pre(t[x].r,v,max(Max,t[x].v)); 61 } 62 int main() 63 { 64 scanf("%d%d%d",&n,&k,&p); 65 insert(rt,0); 66 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 67 for(int i=1;i<=n;i++){ 68 a[i]+=a[i-1]; 69 a[i]%=p; 70 int tem1=pre(rt,a[i]-k,-0x3fffffff); 71 int tem2=pre(rt,a[i]+p-k,-0x3fffffff); 72 mi=min(mi,min(a[i]-tem1,a[i]+p-tem2)); 73 insert(rt,a[i]); 74 } 75 printf("%d\n",mi); 76 return 0; 77 }
View Code

cogs 516【求和】【解題報告】