喂,大家都看到了吧,是 NOI
Online 哦node
既然是線上賽就確定只有Day1的啦ios
開題,網站卡住;卡了好一下子,登陸...卡住...c++
開考10分鐘後我纔看到完整的三道題題面網站
看T1,沒思路;看T2,沒思路;看T3,沒思路...spa
而後心裏就很崩潰code
後來(大概是半小時左右)想到了T2的作法,對於以第i位結尾的逆序對的個數,每次冒泡排序第i位會往前挪一位變成第i-1位,而後逆序對個數同時-1排序
那這樣的話拿個線段樹維護一下,若是i>k且逆序對個數>k的,咱們就把這個逆序對個數減掉k後算進來就是k輪後的逆序對個數了get
而後修改的話逆序對個數只會+1或者-1,隨便寫寫就行了。string
總之不難,可是要特判k>=n的狀況。個人確特判了,可是出現了下面的讓我送命的代碼段。it
if(k>=n)printf("%lld\n",0); printf("%lld\n",query(1,1,n,k+1,n)-k*queryb(1,1,n,k+1,n));
沒錯,少了一個else
。
你覺得這就是結束了嗎?
2h時我開始作T1,只須要按照關係2連個邊,而後再按關係1連邊,看看和能不能變成0就行了。
結果又出現了以下語句。
if(fl)puts("YES\n"); else puts("NO\n");
別問我爲何測樣例的時候沒注意到,我也不知道爲何...
以後還剩半小時看T3...就隨手艹了一個80分的暴力。
你覺得我會得到這最後的80分?不,你錯了,我從新提交文件的時候,新版的尚未保存,我就把舊版的交上去了。
因而考後的估分本來是100+100+80=280的,被我活生生搞成了0+0+0。
可能OI並不適合我。
成績出來了,T2沒有k>=n的數據,我得到了100分。
啊?你問T1和T3?掛了就是掛了呀/kk
T1:
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define int long long int n,m; struct node{ int v; int nxt; }edge[200001]; int cnt; int head[100001]; void add(int a,int c){ edge[++cnt].v=c; edge[cnt].nxt=head[a]; head[a]=cnt; } struct data{ int id,x,y; }t[100001]; int f[100001]; int k[100001]; int fa[100001]; int fx,fy; int tot; int g; int s[100001]; int mp[100001]; bool fl,b[100001],r[100001]; bool cmp(data a,data b){ return a.id>b.id; } int father(int a){ if(fa[a]!=a)fa[a]=father(fa[a]); return fa[a]; } int getfather(int a){ if(s[a]!=a)s[a]=getfather(s[a]); return s[a]; } int find(int u){ if(r[u])r[0ll]=1ll; b[u]=1ll; for(int i=head[u];i;i=edge[i].nxt){ if(!b[edge[i].v])f[u]=f[u]+find(edge[i].v); } return k[u]-f[u]; } void clear(){ fl=1ll; tot=0ll; cnt=0ll; memset(f,0,sizeof(f)); memset(k,0,sizeof(k)); memset(head,0,sizeof(head)); memset(b,0,sizeof(b)); memset(r,0,sizeof(r)); memset(mp,0,sizeof(mp)); } signed main(){ int T; scanf("%lld",&T); while(T){ clear(); T--; scanf("%lld%lld",&n,&m); for(int i=1ll;i<=n;i++){ scanf("%lld",&f[i]); } for(int i=1ll;i<=n;i++){ scanf("%lld",&k[i]); fa[i]=i; } for(int i=1ll;i<=m;i++){ scanf("%lld%lld%lld",&t[i].id,&t[i].x,&t[i].y); } sort(t+1ll,t+m+1ll,cmp); for(int i=1ll;i<=m;i++){ if(t[i].id==1)break; fx=father(t[i].x); fy=father(t[i].y); if(fx!=fy){ fa[fx]=fy; f[fy]=f[fy]+f[fx]; k[fy]=k[fy]+k[fx]; } g=i+1ll; } for(int i=1ll;i<=n;i++){ fa[i]=father(i); if(fa[i]==i){ tot++; mp[i]=tot; s[tot]=tot; f[tot]=f[i]; k[tot]=k[i]; } } for(int i=1ll;i<=n;i++)fa[i]=mp[fa[i]]; for(int i=g;i<=m;i++){ t[i].x=fa[t[i].x]; t[i].y=fa[t[i].y]; if(t[i].x==t[i].y)r[t[i].x]=1ll; fx=getfather(t[i].x); fy=getfather(t[i].y); if(fx!=fy){ add(t[i].x,t[i].y); add(t[i].y,t[i].x); s[fx]=fy; if(r[fx])r[fy]=1ll; } } for(int i=1ll;i<=tot;i++){ if(!b[i]){ r[0ll]=0ll; int a=find(i); if(r[0ll])a=a%2ll; if(a){ fl=0ll; break; } } } if(fl)puts("YES"); else puts("NO");//改過了 } }
T2
#include<bits/stdc++.h> using namespace std; #define int long long int n,m; int lowbit(int x){return x&-x;} int bit[200010]; void upd(int x,int val){ while(x<=n){ bit[x]+=val; x+=lowbit(x); } } int que(int x){ int ans=0; while(x){ ans+=bit[x]; x-=lowbit(x); } return ans; } struct node{ int pos; int val; }b[200010]; bool operator <(node x,node y){ return x.val>y.val; } int a[200010]; struct nod2{ int sum; int x; }num[200010]; int t[1000010]; int bbb[1000010]; void update(int o,int l,int r,int x,int val,int type){ if(x==0)return; if(l==r){ t[o]+=val; bbb[o]+=type; return; } int mid=(l+r)/2; if(x<=mid)update(o<<1,l,mid,x,val,type); else update(o<<1|1,mid+1,r,x,val,type); t[o]=t[o<<1]+t[o<<1|1]; bbb[o]=bbb[o<<1]+bbb[o<<1|1]; } int query(int o,int l,int r,int L,int R){ if(L<=l&&r<=R){ return t[o]; } int ret=0; int mid=(l+r)/2; if(L<=mid)ret+=query(o<<1,l,mid,L,R); if(mid<R)ret+=query(o<<1|1,mid+1,r,L,R); return ret; } int queryb(int o,int l,int r,int L,int R){ if(L<=l&&r<=R){ return bbb[o]; } int ret=0; int mid=(l+r)/2; if(L<=mid)ret+=queryb(o<<1,l,mid,L,R); if(mid<R)ret+=queryb(o<<1|1,mid+1,r,L,R); return ret; } signed main(){ scanf("%lld%lld",&n,&m); for(int i=1;i<=n;++i){ scanf("%lld",&a[i]); b[i].val=a[i],b[i].pos=i; } sort(b+1,b+1+n); for(int i=1;i<=n;++i){ num[b[i].pos].sum=que(b[i].pos); upd(b[i].pos,1); num[b[i].pos].x=min(num[b[i].pos].sum,b[i].pos); update(1,1,n,num[b[i].pos].x,num[b[i].pos].sum,1); } for(int i=1;i<=m;++i){ int opt; scanf("%lld",&opt); if(opt==1){ int x; scanf("%lld",&x); if(a[x]>a[x+1]){ update(1,1,n,num[x].x,-num[x].sum,-1); update(1,1,n,num[x+1].x,-num[x+1].sum,-1); swap(num[x],num[x+1]); swap(a[x],a[x+1]); num[x].sum--; num[x].x=min(num[x].sum,x); num[x+1].x=min(num[x+1].sum,x+1); update(1,1,n,num[x].x,num[x].sum,1); update(1,1,n,num[x+1].x,num[x+1].sum,1); } else if(a[x]==a[x+1])continue; else { update(1,1,n,num[x].x,-num[x].sum,-1); update(1,1,n,num[x+1].x,-num[x+1].sum,-1); swap(num[x],num[x+1]); swap(a[x],a[x+1]); num[x+1].sum++; num[x].x=min(num[x].sum,x); num[x+1].x=min(num[x+1].sum,x+1); update(1,1,n,num[x].x,num[x].sum,1); update(1,1,n,num[x+1].x,num[x+1].sum,1); } } else { int k; scanf("%lld",&k); if(k>=n)printf("%lld\n",0); else printf("%lld\n",query(1,1,n,k+1,n)-k*queryb(1,1,n,k+1,n));//改過了 } } }
T3
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define int long long int n,m; int dp[200001]; int k,ret,p,s; int gcd(int a,int b){ if(a%b==0ll)return b; return gcd(b,a%b); } void find(int a,int b){ int l,r; l=dp[b]; r=dp[b]; while(b>a+1ll){ b--; ret=ret+l*dp[b]; l=dp[b]; b--; ret=ret+r*dp[b]; r=dp[b]; } if(b==a+1)ret=ret+(l+r)*dp[a]; else ret=ret+l*r; } signed main(){ scanf("%lld%lld",&n,&m); for(int i=1ll;i<=n;i++)scanf("%lld",&dp[i]); sort(dp+1ll,dp+n+1ll); for(int i=1ll;i<=m;i++){ scanf("%lld",&k); ret=0ll; if(k==0ll){ for(int j=1ll;j<=n;j++){ ret=ret+dp[j]*dp[j]; } }else{ p=gcd(n,k); s=n/p; for(int j=1ll;j<=n;j=j+s){ find(j,j+s-1ll); } } printf("%lld\n",ret); } }