排名也未知。第1或第5。git
分數也未知,300或260。數組
人生真是大起大落。。。數據結構
啊啊啊啊啊我好感動啊居然重測了一次~~~~~ide
評測機怎麼測怎麼RE,本機怎麼測怎麼AC(任意編譯指令,任意評測平臺)優化
結果原來是系統棧空間開小了致使遞歸爆棧了啊。spa
重測就是把棧空間開到內存限制的大小而後個人代碼就沒鍋了。code
而後去隔壁用評測機調了一個小時也找不到RE的緣由。。。blog
也許是對考場上全程無摸魚一直在思考的獎勵吧。。。排序
然而B哥又被防AK了也是稍慘。遞歸
人生第一次AK非B組題,仍是有一點激動。。。
出題人部分分給的很好,可貴有提示意義。
好事就是讓我這個傻子也想出來了,壞事就是全部人的分數都很高%%%。
因此想在總分上憑這一場來翻身仍是妄想。
繼續加油,沒有懈怠的機會。
畢竟又不是誰都像skyh同樣兩場不考都對排名沒影響。。。
upd:人生真是大起大落我又260了沒AK我感受我在farting。。。爲何要這麼調戲個人感情啊。。。
T1:涼宮春日的憂鬱
寫高精就行了,留300位精度絕對炸不了。
其實double就夠了。求log精度更高。(好像並無300位+比較位數的精度高)
1 //remember to submit 2 #include<cstdio> 3 int max(int a,int b){return a>b?a:b;} 4 struct Int{ 5 long long a[50005];int ws; 6 #define mod 1000000000000 7 friend void operator*=(Int &x,int p){ 8 int W=max(x.ws-25,0); 9 for(int i=x.ws;i>=W;--i)x.a[i]*=p; 10 for(int i=W;i<=x.ws;++i)x.a[i+1]+=x.a[i]/mod,x.a[i]%=mod; 11 if(x.a[x.ws+1])x.ws++; 12 } 13 friend bool operator<=(Int x,Int y){ 14 if(x.ws!=y.ws)return x.ws<y.ws; 15 for(int i=x.ws;~i;--i)if(x.a[i]!=y.a[i])return x.a[i]<y.a[i]; 16 return true; 17 } 18 void reset(){ 19 for(int i=ws;~i;--i)a[i]=0; 20 ws=0;a[0]=1; 21 } 22 }fc,pw; 23 int main(){ 24 freopen("yuuutsu.in","r",stdin); 25 freopen("yuuutsu.out","w",stdout); 26 int t,x,y;scanf("%d",&t); 27 while(t--){ 28 scanf("%d%d",&x,&y); 29 fc.reset();pw.reset(); 30 while(y--)fc*=y+1,pw*=x; 31 puts(pw<=fc?"Yes":"No"); 32 } 33 }
T2:漫無止境的八月
差分。以後操做就是在相距k的位置上一加一減。
其它位互不影響。因此把數組下標直接對k取模便可。
差分的特殊之處在於若是你對序列末尾操做的話會在位置n+1進行加減,而這個位置是幾實際上是沒有關係的。
因此同餘於n+1的位置是否爲0不會對答案產生影響。特判。
修改的話差分數組只改變了兩個位置,判斷是否有新的0出現或消失便可。
1 //remember to submit 2 #include<cstdio> 3 int n,k,q,cnt,p;long long x[2000005]; 4 int read(){ 5 register int p=0,nt=0;register char ch=getchar(); 6 while(ch<'0'||ch>'9')nt=ch=='-',ch=getchar(); 7 while(ch<='9'&&ch>='0')p=(p<<3)+(p<<1)+ch-48,ch=getchar(); 8 return nt?-p:p; 9 } 10 int main(){ 11 freopen("august.in","r",stdin); 12 freopen("august.out","w",stdout); 13 n=read();k=read();q=read(); 14 for(int i=1;i<=n;++i)x[i]=read(); 15 for(int i=n;i;--i)x[i]=x[i]-x[i-1]; 16 for(int i=k;i<=n;++i)x[i%k]+=x[i]; 17 for(int i=0;i<k;++i)if(x[i])cnt++; 18 p=(n+1)%k; 19 if(x[p])cnt--; 20 puts(cnt?"No":"Yes"); 21 for(int i=1,a,b,p1,p2;i<=q;++i){ 22 a=read(),b=read(); 23 p1=a%k;p2=(a+1)%k; 24 if(p1!=p&&x[p1])cnt--; 25 if(p2!=p&&x[p2])cnt--; 26 x[p1]+=b;x[p2]-=b; 27 if(p1!=p&&x[p1])cnt++; 28 if(p2!=p&&x[p2])cnt++; 29 puts(cnt?"No":"Yes"); 30 } 31 }
T3:射手座之日
我複雜度是錯的,極端狀況下是$O(\frac{n^2}{k})$,其中k是一個基於數據的常數
具體範圍我也不知道,我只知道$4 \leq k \leq n$
可是能夠優化到穩定的$O(nlogn)$,常數會很大,和B哥同樣。
看特殊性質部分分,a序列就是dfs序。
那麼問題就是對於每個子區間[l,r]找到最大的p知足$dfn[p]<=l$且$r<=dfr[p]$
其中$dfn/dfr$表示p子樹的dfs序區間。
而「最大這個限制很差處理,咱們把權值作一遍樹上差分,這樣的話問題就轉化成了:對於每個子區間[l,r]找到全部的p知足$dfn[p]<=l$且$r<=dfr[p]$
枚舉p,它的控制區間內的全部子區間都知足條件,那麼答案就是
$\sum\limits_{i=1}^{n} \frac{y[i] \times (dfr[i]-dfn[i]+1) \times (dfr[i]-dfn[i]+2)}{2}$
其中$y$就是$x$數組在樹上差分以後的數組,即$y[i]=x[i]-x[f_i]$
而沒有了特殊性質以後怎麼作?
外層仍是枚舉p的話,內層的式子就不同了,是知足上面條件的子區間數。
其實不考慮有包含關係的子區間,那麼答案就是$y[i] \times \sum \frac{(r-l+1)\times(r-l+2)}{2}$
問題在於求出全部極長子區間。(極長是指不被包含的區間,如[l,r]存在時[l,r-1]不可能存在,而[1,4][7,9]能夠共存)
把問題帶到樹上,考慮一個葉子節點,它的合法區間就是一個點。
其實對於每個點它最開始的合法區間都是本身那一個點,後面還要合併上子樹內的全部點。
考慮怎麼合併。
由於a是一個排列,因此這些區間固然不會有交集,那麼咱們能夠用一個相似與歸併排序的過程來合併區間。
合併的過程當中若是遇到$[L,p]+[p+1,R]$這樣的兩個區間,那麼就把它合併成一個。
在回溯的同時統計$vector$裏面的全部極長區間累加答案便可。
固然這個複雜度不對,雖然也不是很好卡(出題人想不到有這種打法)
然而正解的一種是再也不用$vector$歸併,而是直接用樹上線段樹啓發式合併來維護極長區間。
時間複雜度是$O(nlogn)$的。
由於LNC說我數據結構必掛因此考場上還真的沒有打數據結構2333
1 //remember to submit 2 #include<cstdio> 3 #include<vector> 4 #include<algorithm> 5 using namespace std; 6 vector<int>L[200005],R[200005],reL,reR; 7 int ec,fir[200005],l[200005],to[200005],x[200005],y[200005],dfn[200005],dfr[200005]; 8 int a[200005],tim,n,pos[200005];long long ans; 9 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;} 10 void dfs(int p,int fa){ 11 y[p]=x[p]-x[fa]; dfn[p]=++tim; 12 for(int i=fir[p];i;i=l[i])if(to[i]!=fa)dfs(to[i],p); 13 dfr[p]=tim; 14 } 15 void pushin(int l,int r){ 16 if(reL.empty()||reR[reR.size()-1]!=l-1)return reL.push_back(l),reR.push_back(r),(void)0; 17 reR[reR.size()-1]=r; 18 } 19 void DFS(int p,int fa){ 20 L[p].push_back(pos[dfn[p]]);R[p].push_back(pos[dfn[p]]); 21 for(int i=fir[p];i;i=l[i])if(to[i]!=fa){ 22 DFS(to[i],p); 23 int p1=0,p2=0,e1=L[p].size(),e2=L[to[i]].size(); 24 while(p1<e1&&p2<e2)if(L[p][p1]<L[to[i]][p2])pushin(L[p][p1],R[p][p1]),p1++; 25 else pushin(L[to[i]][p2],R[to[i]][p2]),p2++; 26 while(p1<e1)pushin(L[p][p1],R[p][p1]),p1++; 27 while(p2<e2)pushin(L[to[i]][p2],R[to[i]][p2]),p2++; 28 swap(reL,L[p]);swap(reR,R[p]); 29 reL.clear();reR.clear();L[to[i]].clear();R[to[i]].clear(); 30 }int sz=L[p].size(); 31 for(int i=0;i<sz;++i)ans+=(R[p][i]-L[p][i]+1ll)*(R[p][i]-L[p][i]+2ll)/2*y[p]; 32 } 33 int main(){ 34 freopen("sagittarius.in","r",stdin); 35 freopen("sagittarius.out","w",stdout); 36 scanf("%d",&n); 37 for(int i=2,f;i<=n;++i)scanf("%d",&f),link(f,i); 38 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 39 for(int i=1;i<=n;++i)scanf("%d",&x[i]); 40 dfs(1,0); 41 for(int i=1;i<=n;++i)a[i]=dfn[a[i]],pos[a[i]]=i; 42 DFS(1,0); 43 printf("%lld\n",ans); 44 }