第二次打challenge。。果然还是拿不到钱(艹不过大佬)啊。

A Balanced Contest

模拟就好。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
using namespace std;
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int main()
{int T=read();while (T--){int n=read(),p=read(),a=0,b=0;for (int i=1;i<=n;i++){int x=read();if (x>=p/2) a++;if (x<=p/10) b++;}if (a==1&&b==2) puts("yes");else puts("no");}return 0;
}

Max Mex

题意很脑残,写法很简单。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 1000009
using namespace std;
int a[N];
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int main()
{int T=read();while (T--){int n=read(),k=read();memset(a,0,sizeof(a));for (int i=1;i<=n;i++) a[read()]=1;int ans=0;for (int i=1;i<=k;i++){while (a[ans]==1) ans++;a[ans]=1;}while (a[ans]==1) ans++;printf("%d\n",ans);}return 0;
}

Counter Test For CHEFSUM

构造题,卡了我好久啊。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define mod 4294967296ll
using namespace std;
ll read()
{ll x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;ll s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int main()
{ll T=read();while (T--){ll n=read();ll b=(mod-1)/(n-1);ll c=(mod-1-b*(n-1))/2;if (c>b) c+=mod-(b*(n-1)+2*c);//cout<<b<<" "<<c<<endl;for (ll i=1;i<=n;i++)printf("%lld%s",(i==1)?c:b,(i==n)?"\n":" ");}return 0;
}

Chef and a great voluntary Program

贪心好(差)题。
不要被卡题意是快速AC的关键。(雾)

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 100009
using namespace std;
int n,a,b,x,y;
char str[N];
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int main()
{int T=read();while (T--){scanf("%s",str+1);n=strlen(str+1),a=b=0;for (int i=1;i<=n;i++)if (str[i]=='a') a++;else b++;x=read(),y=read();int num1=a/x,num2=b/y,ans1=0,ans2=0;if (a%x) num1++;if (b>=num1-1) ans1=0;else ans1=a-b*x-x;if (b%y) num2++;if (a>=num2-1) ans2=0;else ans2=b-a*y-y;if (num1*y>=b&&!ans1){int c=b/num1+1,d=b/num1;int c_num=b%num1,d_num=num1-c_num;assert(c*c_num+d*d_num==b);assert((c<=y)||(c_num==0&&c==y+1));for (int i=1;i<=c_num;i++){for (int j=1;j<=x;j++) putchar('a');for (int j=1;j<=c;j++) putchar('b');a-=x;}for (int i=1;i<=d_num;i++){for (int j=1;j<=min(a,x);j++) putchar('a');for (int j=1;j<=d;j++) putchar('b');a-=min(a,x);}assert(a==0);}elseif (num2*x>=a&&!ans2){int c=a/num2+1,d=a/num2;int c_num=a%num2,d_num=num2-c_num;assert(c*c_num+d*d_num==a);assert((c<=x)||(c_num==0&&c==x+1));for (int i=1;i<=c_num;i++){for (int j=1;j<=y;j++) putchar('b');for (int j=1;j<=c;j++) putchar('a');b-=y;}for (int i=1;i<=d_num;i++){for (int j=1;j<=min(b,y);j++) putchar('b');for (int j=1;j<=d;j++) putchar('a');b-=min(b,y);}assert(b==0);}elseif (a>b){while (b--){for (int i=1;i<=x;i++) putchar('a');putchar('b');a-=x;}assert(a>=0);for (int i=1;i<=a;i++){if (i!=1&&(i-1)%x==0) putchar('*');putchar('a');}}else{while (a--){for (int i=1;i<=y;i++) putchar('b');putchar('a');b-=y;}assert(b>=0);for (int i=1;i<=b;i++){if (i!=1&&(i-1)%y==0) putchar('*');putchar('b');}}puts("");}return 0;
}

Chef and Cycled Cycles

一开始看成加强版,后来发现无脑前缀和就好了。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 200009
using namespace std;
int n,q,len[N],st[N],ed[N],val[N],sum[N],sv[N];
vector<int> s[N];
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int Dis(int x,int y,int w)
{if (y>w) swap(y,w);return min(s[x][w-1]-s[x][y-1],s[x][len[x]]-(s[x][w-1]-s[x][y-1]));
}
int main()
{int T=read();while (T--){n=read(),q=read(),sum[0]=sv[0]=0;for (int i=1;i<=n;i++){s[i].resize(1+(len[i]=read()));for (int j=0;j<=len[i];j++) s[i][j]=0;for (int j=1;j<=len[i];j++)s[i][j]=s[i][j-1]+read();}for (int i=1;i<=n;i++)ed[i]=read(),st[i%n+1]=read(),sv[i]=sv[i-1]+read();for (int i=1;i<=n;i++)sum[i]=sum[i-1]+Dis(i,st[i],ed[i]);while (q--){int y=read(),x=read(),w=read(),z=read();if (x>z) swap(x,z),swap(y,w);int ans1=sum[z-1]-sum[x]+sv[z-1]-sv[x-1]+Dis(x,y,ed[x])+Dis(z,w,st[z]);int ans2=sum[n]-(sum[z]-sum[x-1])+sv[n]-(sv[z-1]-sv[x-1])+Dis(x,y,st[x])+Dis(z,w,ed[z]);printf("%d\n",min(ans1,ans2));}}return 0;
}

Chef and Magic Arrays

|x|=max(x,−x)

|x|=max(x,-x)
然后就统计出正负两个最大的那个各转移一下就好啦。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 1000009
#define inf (ll)1e18
using namespace std;
ll n,len[N],dp[N],M1,M2;
vector<ll> a[N];
ll read()
{ll x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;ll s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int main()
{ll T=read();while (T--){n=read();for (ll i=1;i<=n;i++){a[i].resize(len[i]=read());for (ll j=0;j<len[i];j++) a[i][j]=read();}for (ll i=0;i<len[1];i++)dp[i]=0;ll Ans=0;for (ll i=1;i<n;i++){M1=-inf,M2=-inf;for (ll j=0;j<len[i];j++){M1=max(M1,dp[j]+i*a[i][j]);M2=max(M2,dp[j]-i*a[i][j]);}for (ll j=0;j<len[i+1];j++)dp[j]=max(M1-i*a[i+1][(j+1)%len[i+1]],M2+i*a[i+1][(j+1)%len[i+1]]);}for (ll i=0;i<len[n];i++)Ans=max(Ans,dp[i]);printf("%lld\n",Ans);}return 0;
}

Shooting on the array

线段树维护好题。(可能分块也可以过)
跟bzoj上的楼房重建思想没什么区别,主要就是一个calc函数。
calc:在这个区间左边放一个高度xx的柱子后,激光能射到几根柱子。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 1000009
#define root 1,1,n
#define mid (l+r>>1)
#define lc cur<<1
#define rc lc|1
#define lson lc,l,mid
#define rson rc,mid+1,r
#define now cur,l,r
using namespace std;
int n,q,a[N],Max[N<<2],Ans[N<<2];
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
int calc(int cur,int l,int r,int x)
{if (l==r) return Max[cur]>x;if (Max[cur]<=x) return 0;if (Max[lc]<=x) return calc(rson,x);else return Ans[cur]-Ans[lc]+calc(lson,x);
}
void ins(int cur,int l,int r,int x,int y)
{if (l==r){Max[cur]+=y;return;}if (x<=mid) ins(lson,x,y);else ins(rson,x,y);Ans[cur]=Ans[lc]+calc(rson,Max[lc]);Max[cur]=max(Max[lc],Max[rc]);
}
void build(int cur,int l,int r)
{if (l==r){Max[cur]=a[l];Ans[cur]=1;return;}build(lson);build(rson);Ans[cur]=Ans[lc]+calc(rson,Max[lc]);Max[cur]=max(Max[lc],Max[rc]);
}
int Lim(int cur,int l,int r,int L,int R,int x)
{if (l==r){if (Max[cur]>=x) return Max[cur];else return 0;}if (L<=l&&R>=r){if (Max[cur]>=x){if (Max[lc]>=x) return Lim(lson,L,R,x);else return Lim(rson,L,R,x);}else return 0;}if (L<=mid){int tmp=Lim(lson,L,R,x);if (tmp>=x) return tmp;}if (R>mid){int tmp=Lim(rson,L,R,x);if (tmp>=x) return tmp;}return 0;
}
int Ma;
int qry(int cur,int l,int r,int L,int R)
{if (L<=l&&R>=r){int tmp=calc(now,Ma);Ma=max(Ma,Max[cur]);return tmp;}int ret=0;if (L<=mid) ret=qry(lson,L,R);if (R>mid) ret+=qry(rson,L,R);return ret;
}
int main()
{int T=read();while (T--){n=read(),q=read();for (int i=1;i<=n;i++) a[i]=read();build(root);while (q--){char ch;while (ch=gc,ch!='?'&&ch!='+');if (ch=='?'){int i=read(),l=read(),r=read();int lim=Lim(root,i,n,r);if (lim){Ma=l-1;int ans1=qry(root,i,n);Ma=lim;int ans2=qry(root,i,n);printf("%d\n",ans1-ans2);}else{Ma=l-1;int ans1=qry(root,i,n);printf("%d\n",ans1);}}else{int x=read(),y=read();ins(root,x,y);}}}return 0;
}

Lucky Edge

这道题告诉我们,只要有信仰,卡常数暴力是可以过的。

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 10009
using namespace std;
int n,m,first[N],number,dy[N],id[N],used[N],Ans[N],fa[N],pnt[N];
int deep[N],q[N],to[N],sta[N],top,rk[N],head,tail,a[N],b[N];
int t[N],nxt[N],v[N];
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);
}
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
void bfs(int x)
{head=1,tail=0;q[++tail]=x;pnt[x]=0;while (head<=tail){x=q[head++];for (register int i=first[x];i;i=nxt[i])if (t[i]!=pnt[x]){pnt[t[i]]=x;q[++tail]=t[i];deep[t[i]]=deep[x]+1;to[t[i]]=v[i];}}
}
int main()
{int T=read(),x,y;while (T--){m=read();n=0;memset(dy,0,sizeof(dy));memset(Ans,0,sizeof(Ans));for (register int i=1;i<=m;i++){x=read();y=read();if (!dy[x]) dy[x]=++n;if (!dy[y]) dy[y]=++n;a[i]=dy[x],b[i]=dy[y];}for (register int l=1;l<=m;l++){number=1;for (register int i=1;i<=n;i++){rk[i]=first[i]=pnt[i]=0;fa[i]=i;}for (register int i=l;i<=m;i++){used[i]=0;x=find(a[i]);y=find(b[i]);if (x!=y){if (rk[x]>rk[y]) swap(x,y);used[i]=1;fa[x]=y;if (rk[x]==rk[y]) rk[y]++;t[++number]=b[i];nxt[number]=first[a[i]];v[number]=i;first[a[i]]=number;t[++number]=a[i];nxt[number]=first[b[i]];v[number]=i;first[b[i]]=number;}}for (register int i=1;i<=n;i++){if (!pnt[i]) bfs(i);fa[i]=i;}for (register int i=l;i<=m;i++){if (used[i]) continue;x=find(a[i]);y=find(b[i]);top=0;while (x!=y){if (deep[x]<deep[y]) swap(x,y);Ans[to[x]]+=m-i+1;sta[++top]=x;x=find(pnt[x]);}Ans[i]+=m-i+1;while (top) fa[sta[top--]]=x;}}for (int i=1;i<=m;i++) printf("%d%s",Ans[i],i==m?"\n":" ");}return 0;
}

Chef and Horcrux

这道题先算出答案为某个值xx的概率pxp_x,然后就是kk进制下的FWT即可。然后考虑如何trans,发现kk个数配个系数就好,然后发现系数就是kk次单位根,然后就没了。。(模数原根为22)

#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 1000009
#define mod 330301441
#define M 11
using namespace std;
int n,k,p[N],num[N],INV,w[2][N];
ll x;
int ksm(int x,ll y,int mo=mod,int ret=1)
{for (;y;y>>=1ll,x=(ll)x*x%mo) if (y&1ll) ret=(ll)ret*x%mo;return ret;
}
int inv(int x)
{return ksm(x,mod-2);
}
int read()
{int x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;int s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
ll Read()
{ll x=1;char ch;while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;ll s=ch-'0';while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';return x*s;
}
void init(int &n)
{int ret=1;for (;ret<=n;ret*=k);n=ret;int G=ksm(22,(mod-1)/k);w[0][0]=w[0][k]=w[1][0]=w[1][k]=1;for (int i=1;i<k;i++) w[0][i]=(ll)w[0][i-1]*G%mod;for (int i=1;i<k;i++) w[1][i]=w[0][k-i];
}
ll b[M];
void FWT(int a[],int n)
{for (int d=1;d<n;d*=k)for (int m=d*k,i=0;i<n;i+=m)for (int j=0;j<d;j++){for (int l=0;l<k;l++){b[l]=0;for (int r=0;r<k;r++)b[l]=b[l]+(ll)a[i+j+d*r]*w[0][l*r%k];}for (int l=0;l<k;l++)a[i+j+d*l]=b[l]%mod;}
}
void UFWT(int a[],int n)
{for (int d=1;d<n;d*=k)for (int m=d*k,i=0;i<n;i+=m)for (int j=0;j<d;j++){for (int l=0;l<k;l++){b[l]=0;for (int r=0;r<k;r++)b[l]=b[l]+(ll)a[i+j+d*r]*w[1][l*r%k];}for (int l=0;l<k;l++)a[i+j+d*l]=b[l]%mod;}for (int i=0;i<n;i++) a[i]=(ll)a[i]*INV%mod;
}
int main()
{int T=read();while (T--){n=read(),k=read(),x=Read();for (int i=0;i<=100000;i++) num[i]=0;memset(p,0,sizeof(p));for (int i=1;i<=n;i++) num[read()]++;int sum=1,rest=n;int m=0;for (int i=0;i<=100000;i++){rest-=num[i];p[i]=(ll)sum*ksm(2,rest)%mod;p[i]=(ll)p[i]*inv(ksm(2,n))%mod;sum=(ll)sum*(ksm(2,num[i])-1)%mod;if (p[i]) m=i;}init(m);INV=inv(m);FWT(p,m);for (int i=0;i<m;i++) p[i]=ksm(p[i],x);UFWT(p,m);int Ans=0;for (int i=0;i<m;i++)Ans=(Ans+(ll)ksm(p[i],3*i)*ksm(i,2*i)%mod)%mod;printf("%d\n",Ans);}return 0;
}

(Challenge) Connecting computers

到最后还是只有91分啊。。果然技不如人。。
题意就是给一张无向图,告诉你连边(i,j)(i,j)代价C[i][j]C[i][j],某个点ii度数为jj的代价H[i][j]H[i][j]。让你在保证图联通的情况下,最小化代价。
考虑给每个点一个度数(度数代价最小的度数),然后尽量去满足,边从小到大加入,这样的话,最后可能不连通,然后就用用最小的代价合并连通块。然后主要就是调试参数(度数上限,加边上限)和加优化(三个点换边,四个点换边等等)。
似乎这样就有90分了。(但还是不懂100分的大佬是怎么搞得啊)

#include <bits/stdc++.h>
#define ull unsigned long long
#define ll long long
#define N 1002
#define M 1000009
#define int_inf 1000000000
#define ll_inf 1000000000000000000ll
#define rep(a,b,c) for(int a = b;a <= c;a++)
#define REP(a,b,c) for(int a = b;a <  c;a++)
#define per(a,b,c) for(int a = b;a >= c;a--)
#define PER(a,b,c) for(int a = b;a >  c;a--)
#define debug 1
using namespace std;
int First[N],Number,ss[N],used[N];
struct Edge
{int to,next;void add(int x,int y){to=y,next=First[x],First[x]=Number;}
}E[N*N];
struct edge
{int x,y,z;bool operator <(const edge &rhs) const{return z<rhs.z;}
}e[N*N],g[N*N];
int C[N][N],H[N][N],fa[N],Ans[N][N],ans[N][N];
int S,B,L,g_number,del_number,c[N][N],h[N][N];
int n,Cmax,Hmax,number,d[N],D[N];
int A[5],id,Min[5],Max[5];
ll Mi_Ans,Mi_pos,res;
char ch[N][N];
bool vis[N][N];
ull s[2];
ull xorshift128plus()
{ull x=s[0];const ull y=s[1];x^=x<<23;s[1]=x^y^(x>>17)^(y>>26);return s[0]= y;
}
struct node
{int x,dis;bool operator <(const node &rhs) const{return dis<rhs.dis;}node(int x=0,int dis=0):x(x),dis(dis){}
};
struct Node
{int x,y;bool operator <(const Node &rhs) const{return x<rhs.x||x==rhs.x&&y<rhs.y;}
};
struct circle
{int x,y,z,val;bool operator <(const circle &rhs) const{return val<rhs.val;}
}del[N];
unsigned long rng(unsigned long e = 0)
{static unsigned long t = 0, x = 123456789, y = 362436069, z = 521288629, w = 88675123, v = 5783321, d = 6615241;d += e; x += d; t = (x ^ (x >> 2)); x = y; y = z; z = w; w = v; v = (v ^ (v << 4)) ^ (t ^ (t << 1));return e ? (((d += 362437) + v) % e) : ((d += 362437) + v);
}
struct EulerTourTree {struct node {node *lch = nullptr;node *rch = nullptr;node *parent = nullptr;unsigned int size = 1;int vid;bool active = false;unsigned int sub = 0;node(int vid) : vid(vid) {}};unsigned int size(node *x) {return x != nullptr ? x->size : 0;}unsigned int sub(node *x) {return x != nullptr ? x->sub : 0;}node *update(node *x) {if (x == nullptr) return x;x->size = 1 + size(x->lch) + size(x->rch);x->sub = sub(x->lch) + sub(x->rch);if (x->active) x->sub++;return x;}void update_ancestor(node *x) {if (x == nullptr) return;x = update(x);update_ancestor(x->parent);}void activate(node *x, bool value) {if (x == nullptr) return;x->active = value;update_ancestor(x);}node *merge(node *x, node *y) {if (x == nullptr) return y;if (y == nullptr) return x;if (rng() % (size(x) + size(y)) < size(x)) {x->rch = merge(x->rch, y);if (x->rch != nullptr) x->rch->parent = x;return update(x);} else {y->lch = merge(x, y->lch);if (y->lch != nullptr) y->lch->parent = y;return update(y);}}pair<node *, node *> split(node *x, unsigned k) {if (x == nullptr) return make_pair(nullptr, nullptr);if (k <= size(x->lch)) {auto p = split(x->lch, k);x->lch = p.second;if (p.first != nullptr) p.first->parent = nullptr;if (p.second != nullptr) p.second->parent = x;return make_pair(p.first, update(x));} else {auto p = split(x->rch, k - size(x->lch) - 1);x->rch = p.first;if (p.first != nullptr) p.first->parent = x;if (p.second != nullptr) p.second->parent = nullptr;return make_pair(update(x), p.second);}}node *root(node *x) {if (x == nullptr) return x;if (x->parent == nullptr) return x;return root(x->parent);}int index_of(node *x) {if (x == nullptr) return 0;int result = -1;bool l = true;while (x != nullptr) {if (l) result += 1 + size(x->lch);if (x->parent == nullptr) break;l = x->parent->rch == x;x = x->parent;}return result;}void connected_component(node *x, vector<int> &res) {if (x == nullptr) return;if (x->active) res.push_back(x->vid);connected_component(x->lch, res);connected_component(x->rch, res);}vector<int> connected_component(int u) {node *x = root(any_node(u));if (x == nullptr) return{ u };vector<int> res;connected_component(x, res);return res;}vector<map<int, node *>> tr;EulerTourTree(int n) : tr(n) {}node *any_node(int u) {return tr[u].empty() ? nullptr : tr[u].begin()->second;}bool link(int u, int v) {node *x = any_node(u);node *y = any_node(v);node *root_x = root(x);node *root_y = root(y);if (root_x != nullptr && root_x == root_y) return false;node *A, *B, *C, *D;tie(A, B) = split(root_x, index_of(x));tie(C, D) = split(root_y, index_of(y));// AB, CD => A (u->v) D C (v->u) Bnode *uv = new node(u);node *vu = new node(v);if (tr[u].empty()) activate(uv, true);if (tr[v].empty()) activate(vu, true);tr[u][v] = uv;tr[v][u] = vu;A = merge(A, uv);A = merge(A, D);A = merge(A, C);A = merge(A, vu);A = merge(A, B);return true;}bool cut(int u, int v) {if (tr[u].count(v) == 0) return false;node *uv = tr[u][v];node *vu = tr[v][u];tr[u].erase(v);tr[v].erase(u);if (uv->active) {activate(uv, false);activate(any_node(u), true);}if (vu->active) {activate(vu, false);activate(any_node(v), true);}node *rt = root(uv);int index_uv = index_of(uv);int index_vu = index_of(vu);if (index_uv > index_vu) swap(index_uv, index_vu);node *A, *B;auto p = split(rt, index_vu);B = split(p.second, 1).second;auto q = split(p.first, index_uv);A = q.first;split(q.second, 1);merge(B, A);return true;}bool is_connected(int u, int v) {if (u == v) return true;node *x = any_node(u);node *y = any_node(v);return x != nullptr && root(x) == root(y);}int sub(int u) {node *x = any_node(u);if (x == nullptr) return 1;return sub(root(x));}
};struct HolmDeLichtenbergThorup {static const int L = 20;vector<EulerTourTree> et;vector<vector<set<int>>> g;vector<vector<set<int>>> gg;HolmDeLichtenbergThorup(int n) :et(L, EulerTourTree(n)),g(L, vector<set<int>>(n)),gg(L, vector<set<int>>(n)) {}bool insert(int u, int v) {if (!et[0].is_connected(u, v)) {assert(et[0].link(u, v));gg[0][u].insert(v);gg[0][v].insert(u);return true;} else {g[0][u].insert(v);g[0][v].insert(u);return false;}}bool erase(int u, int v) {bool is_tree = false;int level = -1;for (int i = 0; i < L && level == -1; i++) {et[i].cut(u, v);if (gg[i][u].count(v) == 1) {gg[i][u].erase(v);gg[i][v].erase(u);level = i;is_tree = true;}if (g[i][u].count(v) == 1) {g[i][u].erase(v);g[i][v].erase(u);level = i;}}assert(level != -1);if (!is_tree) return false;return reconnect(level, u, v);}bool reconnect(int level, int u, int v) {if (level == -1) return true;int size_u = et[level].sub(u);int size_v = et[level].sub(v);if (size_u > size_v) swap(u, v);vector<int> cc = et[level].connected_component(u);for (int x : cc) {auto &st = gg[level][x];for (auto it = st.begin(); it != st.end();) {int y = *it;st.erase(it++);gg[level][y].erase(x);gg[level + 1][x].insert(y);gg[level + 1][y].insert(x);assert(et[level + 1].link(x, y));}}for (int x : cc) {auto &st = g[level][x];for (auto it = st.begin(); it != st.end();) {int y = *it;if (et[level].is_connected(y, v)) {st.erase(it++);g[level][y].erase(x);gg[level][x].insert(y);gg[level][y].insert(x);for (int i = 0; i <= level; i++) {assert(et[i].link(x, y));}return false;} else {st.erase(it++);g[level][y].erase(x);g[level + 1][x].insert(y);g[level + 1][y].insert(x);}}}return reconnect(level - 1, u, v);}bool is_connected(int u, int v) {return et[0].is_connected(u, v);}int size_connected_component(int u) {return et[0].sub(u);}
} ;
void Atoa()
{for (int i=0;i<n;i++)for (int j=0;j<n;j++) ans[i][j]=Ans[i][j];
}
void atoA()
{for (int i=0;i<n;i++)for (int j=0;j<n;j++) Ans[i][j]=ans[i][j];
}
int find(int x)
{return fa[x]==x?x:fa[x]=find(fa[x]);
}
void print()
{for (int i=0;i<n;i++){for (int j=0;j<n;j++) printf("%d",Ans[i][j]);puts("");}
}
ll Get()
{ll ret=0;for (int i=0;i<n;i++){for (int j=i+1;j<n;j++)if (Ans[i][j]) ret+=(ll)C[i][j];int x=0;for (int j=0;j<n;j++)if (Ans[i][j]) x++;ret+=(ll)H[i][x];}return ret;
}
ll get()
{ll ret=0;for (int i=0;i<n;i++){for (int j=i+1;j<n;j++)if (ans[i][j]) ret+=(ll)C[i][j];int x=0;for (int j=0;j<n;j++)if (ans[i][j]) x++;ret+=(ll)H[i][x];}return ret;
}
void trans()
{for (int i=n;i;i--){for (int j=n;j>=0;j--){if (j) c[i][j]=C[i-1][j-1];h[i][j]=H[i-1][j];}c[i][i]=0,h[i][n]=int_inf;}
}
int not0(int *a,int n)
{int ret=0;for (int i=1;i<=n;i++)if (a[i]) ret++;return ret;
}
void test1(int &lim)
{static int q[M];int cnt=0;for (int i=1;i<=n;i++)if (!d[i])for (int j=1;j<=n;j++)if (d[j]&&!vis[i][j])q[++cnt]=h[i][D[i]+1]-h[i][D[i]]+c[i][j];sort(q+1,q+cnt+1);lim=q[min(cnt,L)];
}
void work1(int lim)
{static edge q[M];int cnt=0;for (int i=1;i<=n;i++)if (!d[i]&&h[i][D[i]+1]-h[i][D[i]]<lim)for (int j=1;j<=n;j++)if (d[j]&&!vis[i][j])q[++cnt]=(edge){i,j,h[i][D[i]+1]-h[i][D[i]]+c[i][j]};sort(q+1,q+cnt+1);for (int i=1;i<=cnt;i++){int x=q[i].x,y=q[i].y;if (d[y]&&h[x][D[x]+1]-h[x][D[x]]+c[x][y]<=lim){D[x]++,d[y]--;g[++g_number]=(edge){x,y,c[x][y]};vis[x][y]=vis[y][x]=1;}}
}
void add_rest()
{static Node q[N];for (int i=1;i<=n;i++)while (d[i]){int tp=0;for (int j=1;j<=n;j++)if (i!=j&&!vis[i][j])q[++tp]=(Node){h[j][D[j]+1]-h[j][D[j]]+c[i][j],j};sort(q+1,q+tp+1);int j=q[1].y;g[++g_number]=(edge){i,j,c[i][j]};vis[i][j]=vis[j][i]=1;d[i]--,D[j]++;}
}
void merge_block()
{static int q[N];static Node a[N],b[N];for (int i=1;i<=n;i++) fa[i]=i;for (int i=1;i<=g_number;i++){int x=g[i].x,y=g[i].y;fa[find(x)]=find(y);}int block_cnt=0,tp=0,na,nb;for (int i=1;i<=n;i++)if (find(i)==i) block_cnt++;while (block_cnt>1){tp=na=nb=0;for (int i=1;i<=n;i++)if (find(i)==i) q[++tp]=i;for (int i=1;i<=n;i++)if (find(i)==q[1])a[++na]=(Node){h[i][D[i]+1]-h[i][D[i]],i};elseif (find(i)==q[2])b[++nb]=(Node){h[i][D[i]+1]-h[i][D[i]],i};sort(a+1,a+na+1),sort(b+1,b+nb+1);int mn=int_inf,x,y,tx=q[1],ty=q[2];for (int i=1;i<=na;i++)for (int j=1;j<=nb;j++){int x=a[i].y,y=b[j].y;if (!vis[x][y]&&c[x][y]+a[i].x+b[j].x<mn){mn=c[x][y]+a[i].x+b[j].x;tx=x,ty=y;}}g[++g_number]=(edge){tx,ty,c[tx][ty]};vis[tx][ty]=vis[ty][tx]=1;D[tx]++,D[ty]++;fa[find(tx)]=find(ty);block_cnt--;}
}
void get_Ans()
{static int d[N];int x,y;memset(d,0,sizeof(d));for (int i=0;i<n;i++)for (int j=0;j<n;j++) Ans[i][j]=0;for (int i=1;i<=g_number;i++){x=g[i].x,y=g[i].y;d[x]++,d[y]++;Ans[x-1][y-1]=Ans[y-1][x-1]=1;}int tt=3;while (tt--){for (int i=1;i<n;i++)for (int j=i+1;j<=n;j++)if (!vis[i][j]){int tmp=h[i][d[i]+1]-h[i][d[i]];tmp+=h[j][d[j]+1]-h[j][d[j]];if (tmp+c[i][j]<0){vis[i][j]=vis[j][i]=1;Ans[i-1][j-1]=Ans[j-1][i-1]=1;d[i]++,d[j]++;}}}
}
void solve()
{memset(vis,0,sizeof(vis));int x,y;for (int i=1;i<=n;i++) vis[i][i]=1;for (int i=1;i<=n;i++){D[i]=1;for (int j=2;j<=min(S,ss[i]);j++)if (h[i][j]<h[i][D[i]]) D[i]=j;}g_number=0;for (int i=1;i<=n;i++) d[i]=D[i];for (int i=1;i<=number;i++) e[i].x++,e[i].y++;for (int i=1;i<=number/B;i++){x=e[i].x,y=e[i].y;if (x==n||y==n) continue;if (d[x]>0&&d[y]>0){d[x]--,d[y]--;g[++g_number]=(edge){x,y,e[i].z};vis[x][y]=vis[y][x]=1;}}for (int i=1;i<=n;i++) ss[i]=D[i]-d[i];int work1_lim=0;test1(work1_lim);for (int i=1;i<100;i++){work1(work1_lim);if (not0(d,n-1)<3) break;}add_rest();merge_block();get_Ans();ll tmp=Get();if (tmp<Mi_Ans){Mi_Ans=tmp;Atoa();}for (int i=1;i<=number;i++) e[i].x--,e[i].y--;
}
void change()
{Number=0;for (int i=0;i<n;i++) First[i]=0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j])E[++Number].add(i,j),E[++Number].add(j,i);g_number=0;for (int i=1;i<=number&&g_number<17000;i++)if (!Ans[e[i].x][e[i].y]) g[++g_number]=e[i];for (int i=1;i<=g_number;i++)for (int x=First[g[i].x];x;x=E[x].next)for (int y=First[g[i].y];y;y=E[y].next)if (E[x].to!=E[y].to&&Ans[g[i].y][E[y].to]&&Ans[g[i].x][E[x].to])if (!Ans[g[i].x][g[i].y]&&!Ans[E[x].to][E[y].to])if (C[E[x].to][E[y].to]+g[i].z<C[g[i].x][E[x].to]+C[g[i].y][E[y].to]){Ans[E[x].to][E[y].to]=Ans[E[y].to][E[x].to]=1;Ans[g[i].x][g[i].y]=Ans[g[i].y][g[i].x]=1;Ans[g[i].x][E[x].to]=Ans[E[x].to][g[i].x]=0;Ans[g[i].y][E[y].to]=Ans[E[y].to][g[i].y]=0;}
}
void init()
{for (int i=1;i<=n;i++) ss[i]=int_inf;Mi_Ans=ll_inf;for (int i=0;i<n;i++)for (int j=0;j<n;j++) ans[i][j]=0;
}
void WORK0()
{B=1,S=48;init();for (int i=1;i<=20;i++) solve();atoA();for (int i=1;i<=13;i++) change();
}
void WORK1()
{B=1,S=35;init();for (int i=1;i<=20;i++) solve();atoA();for (int i=1;i<=13;i++) change();
}
void WORK2()
{B=2,S=29,L=30;init();for (int i=1;i<=20;i++) solve();atoA();for (int i=1;i<=13;i++) change();
}
void WORK3()
{B=4,S=24,L=30;init();for (int i=1;i<=20;i++) solve();atoA();for (int i=1;i<=13;i++) change();
}
void WORK4()
{B=6,S=18,L=30;init();for (int i=1;i<=20;i++) solve();atoA();for (int i=1;i<=13;i++) change();
}
void get_d()
{for (int i=0;i<n;i++){d[i]=0;for (int j=0;j<n;j++)if (Ans[i][j]) d[i]++;}
}
void Delete()
{get_d();HolmDeLichtenbergThorup HdLT(n+1);for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j]) HdLT.insert(i,j);g_number=0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j]) g[++g_number]=(edge){i,j,C[i][j]};for (int i=1;i<=g_number;i++)if (Ans[g[i].x][g[i].y]&&g[i].z+H[g[i].x][d[g[i].x]]+H[g[i].y][d[g[i].y]]>H[g[i].x][d[g[i].x]-1]+H[g[i].y][d[g[i].y]-1]){HdLT.erase(g[i].x,g[i].y);if (!HdLT.is_connected(g[i].x,g[i].y))HdLT.insert(g[i].x,g[i].y);else{Ans[g[i].x][g[i].y]=Ans[g[i].y][g[i].x]=0;d[g[i].x]--,d[g[i].y]--;}}
}
void Delete_two()
{get_d();for (int i=0;i<n;i++) used[i]=0;g_number=0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j]&&!used[i]&&!used[j])if (C[i][j]+H[i][d[i]]+H[j][d[j]]>H[i][d[i]-1]+H[j][d[j]-1]){Ans[i][j]=Ans[j][i]=0;d[i]--,d[j]--;used[i]=used[j]=1;g[++g_number]=(edge){i,j,C[i][j]};}int block_num=0;for (int i=0;i<n;i++) fa[i]=i;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j])if (find(i)!=find(j)) fa[find(i)]=find(j);for (int i=0;i<n;i++)if (find(i)==i) block_num++;sort(g+1,g+g_number+1);int pos=1;while (block_num>1){while (find(g[pos].x)==find(g[pos].y)) pos++;Ans[g[pos].x][g[pos].y]=Ans[g[pos].y][g[pos].x]=1;fa[find(g[pos].x)]=find(g[pos].y);block_num--;}
}
void add_circle()
{for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (!Ans[i][j])for (int k=j+1;k<n;k++)if (!Ans[i][j]&&!Ans[i][k]&&!Ans[j][k])if (C[i][j]+C[i][k]+C[j][k]+H[i][d[i]+2]+H[j][d[j]+2]+H[k][d[k]+2]<H[i][d[i]]+H[j][d[j]]+H[k][d[k]]){d[i]+=2,d[j]+=2,d[k]+=2;Ans[i][j]=Ans[j][i]=1;Ans[i][k]=Ans[k][i]=1;Ans[j][k]=Ans[k][j]=1;}
}
void del_circle()
{HolmDeLichtenbergThorup HdLT(n+1);for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j]) HdLT.insert(i,j);for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j])for (int k=j+1;k<n;k++)if (Ans[i][j]&&Ans[i][k]&&Ans[j][k])if (C[i][j]+C[i][k]+C[j][k]+H[i][d[i]]+H[j][d[j]]+H[k][d[k]]>H[i][d[i]-2]+H[j][d[j]-2]+H[k][d[k]-2]){HdLT.erase(i,j);HdLT.erase(j,k);HdLT.erase(i,k);if (HdLT.is_connected(i,j)&&HdLT.is_connected(j,k)){d[i]-=2,d[j]-=2,d[k]-=2;Ans[i][j]=Ans[j][i]=0;Ans[i][k]=Ans[k][i]=0;Ans[j][k]=Ans[k][j]=0;}else{HdLT.insert(i,j);HdLT.insert(j,k);HdLT.insert(i,k);}}
}
void one_to_two()
{g_number=0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j]) g[++g_number]=(edge){i,j,C[i][j]};for (int i=1;i<=g_number;i++)if (Ans[g[i].x][g[i].y])for (int j=0;j<n;j++)if (!Ans[g[i].x][j]&&!Ans[g[i].y][j]&&Ans[g[i].x][g[i].y])if (C[j][g[i].x]+C[j][g[i].y]+H[j][d[j]+2]<g[i].z+H[j][d[j]]){d[j]+=2;Ans[g[i].x][g[i].y]=Ans[g[i].y][g[i].x]=0;Ans[j][g[i].x]=Ans[g[i].x][j]=1;Ans[j][g[i].y]=Ans[g[i].y][j]=1;break;}
}
void two_to_one()
{HolmDeLichtenbergThorup HdLT(n+1);for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j]) HdLT.insert(i,j);g_number=0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (!Ans[i][j]) g[++g_number]=(edge){i,j,C[i][j]};sort(g+1,g+g_number+1);for (int i=1;i<=g_number/5;i++)if (!Ans[g[i].x][g[i].y])for (int j=0;j<n;j++)if (Ans[g[i].x][j]&&Ans[g[i].y][j]&&!Ans[g[i].x][g[i].y])if (C[j][g[i].x]+C[j][g[i].y]+H[j][d[j]]>g[i].z+H[j][d[j]-2]){HdLT.erase(j,g[i].x);HdLT.erase(j,g[i].y);HdLT.insert(g[i].x,g[i].y);if (HdLT.is_connected(g[i].x,j)){d[j]-=2;Ans[g[i].x][g[i].y]=Ans[g[i].y][g[i].x]=1;Ans[j][g[i].x]=Ans[g[i].x][j]=0;Ans[j][g[i].y]=Ans[g[i].y][j]=0;break;}else{HdLT.insert(j,g[i].x);HdLT.insert(j,g[i].y);HdLT.erase(g[i].x,g[i].y);}}
}
void circle_change()
{Number=0;for (int i=0;i<n;i++) First[i]=0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j])E[++Number].add(i,j),E[++Number].add(j,i);for (int i=0;i<n;i++)for (int x=First[i];x;x=E[x].next)for (int y=E[x].next;y;y=E[y].next)if (Ans[i][E[x].to]&&Ans[i][E[y].to]&&!Ans[E[x].to][E[y].to]){int j=E[x].to,k=E[y].to;if (C[i][j]+H[i][d[i]]+H[k][d[k]]>C[j][k]+H[i][d[i]-1]+H[k][d[k]+1]){d[i]--,d[k]++;Ans[i][j]=Ans[j][i]=0;Ans[j][k]=Ans[k][j]=1;break;}if (C[i][k]+H[i][d[i]]+H[j][d[j]]>C[j][k]+H[i][d[i]-1]+H[j][d[j]+1]){d[i]--,d[j]++;Ans[i][k]=Ans[k][i]=0;Ans[j][k]=Ans[k][j]=1;break;}}
}
bool check()
{for (int i=0;i<n;i++) fa[i]=i;for (int i=0;i<n;i++) if (Ans[i][i]) return 0;for (int i=0;i<n;i++)for (int j=i+1;j<n;j++)if (Ans[i][j])if (find(i)!=find(j)) fa[find(i)]=find(j);int num=0;for (int i=0;i<n;i++)if (find(i)==i) num++;return num==1;
}
int main()
{if (debug){freopen("1.in","r",stdin);freopen("1.out","w",stdout);}srand(20010527);int T;scanf("%d",&T);Min[0]=43,Max[0]=48;Min[1]=30,Max[1]=35;Min[2]=25,Max[2]=29;Min[3]=17,Max[3]=21;Min[4]=13,Max[4]=16;ll ret=0;for (int tt=0;tt<T;tt++){scanf("%d %d %d",&n,&Cmax,&Hmax);if (Cmax==40000) id=0;if (Cmax==100000) id=1;if (Cmax==200000) id=2;if (Cmax==500000) id=3;if (Cmax==1000000) id=4;number=0;memset(Ans,0,sizeof(Ans));for (int i=0;i<n;i++){C[i][i]=0;scanf("%llu %llu",&s[0],&s[1]);for (int j=i+1;j<n;j++){C[i][j]=C[j][i]=xorshift128plus()%(Cmax+1);e[++number]=(edge){i,j,C[i][j]};}}for (int i=0;i<n;i++){scanf("%llu %llu",&s[0],&s[1]);for (int j=0;j<n;j++)H[i][j]=xorshift128plus()%(Hmax+1);}trans();sort(e+1,e+number+1);if (id==0) WORK0();if (id==1) WORK1();if (id==2) WORK2();if (id==3) WORK3();if (id==4) WORK4();//Delete();Delete_two();get_d();for (int i=0;i<3;i++) one_to_two();two_to_one();//if (id>=4) add_circle();circle_change();//del_circle();assert(check());print();ret+=Get();cerr<<Get()<<endl;}cerr<<"The score is: "<<ret<<endl;return 0;
}

codechef October Challenge 2017解题报告相关推荐

  1. codechef November Challenge 2017解题报告

    第二次被ceilks艹翻的无奈啊.. Villages and Tribes 模拟不解释 #include <bits/stdc++.h> #define gc getchar() #de ...

  2. CFCC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

  3. CodeChef June Challenge 2017

    好气啊,本来以为比赛时间还有很多,结果回家养病两天回到学校怎么比赛就结束了(雾),大约是小高考弄错了时间? 挑3道有意思的写写题解吧. Cloning 题目大意:给一个序列,每次询问两个等长区间,问区 ...

  4. CodeChef March Challenge 2017 题解

    CC XENTASK 由于要交替选,所以要不第一个人选位置为奇数的数,第二个人选位置为偶数的数,要不第一个人选位置为偶数的数,第二个人选位置为奇数的数.取最小值即可. #include <cst ...

  5. [CodeChef FEB15]Payton numbers(CUSTPRIM)解题报告

    题目 https://www.codechef.com/problems/CUSTPRIM (翻译来自洪华敦) 定义三元组的乘法 def multiply((a1,b1,c1), (a2,b2,c2) ...

  6. 【网易2017春招】赶去公司 解题报告

    [网易2017春招]赶去公司 解题报告 标签(空格分隔): 牛客网 题目地址:https://www.nowcoder.com/questionTerminal/5c7657015d3d49369c4 ...

  7. LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告

    LOJ#6072. 「2017 山东一轮集训 Day5」苹果树 解题报告 好苹果会组成连通块,整棵树的权值为 ∑ i = 1 n c i [ c i ≥ 0 ] [ s i z n u m ( c i ...

  8. LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告

    LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告 前置知识:闭区间上的连续函数的零点存在性定理: 我们定义这样的函数: 定义域为 [ l , r ] ∩ Z [l,r]\cap ...

  9. [zz][ZOJ Monthly]October 2008解题报告

    Connect4 Connect Four(Author: SONG, Yu[EZdestroyer]) 题目的背景就是Linux下的同名游戏,两个人在7*7的槽里轮流扔棋子,每次棋子都扔进某一列,棋 ...

最新文章

  1. 「它将改变一切」,DeepMind AI解决生物学50年来重大挑战,破解蛋白质分子折叠问题...
  2. cocos2d笔记——CCNode与CCAction
  3. android 滑动冲突
  4. 关刀机器人_小学机器人活动总结
  5. Eclipse-无法引用maven依赖的类/没有MavenDependencies/没有buildpath
  6. MyReport.TD套打引擎介绍
  7. python bp神经网络进行预测_python实现BP神经网络回归预测模型
  8. MySQL移动数据目录出现权限问题
  9. ORACLE GOLDENGATE: WHAT IS ADD TRANDATA REALLY DOING?
  10. SOAPUI接口测试学习网站
  11. 几款常用的Git图形化工具
  12. 双击java安装包没有反应_雨林木风Win7下双击JER安装包没有反应的解决技巧
  13. VLC播放电视直播rtmp流地址
  14. Gale-Shapley 稳定匹配算法的C++实现
  15. vncview用法_vnc远程桌面怎么使用(最新vncviewer使用教程)
  16. FATAL Exited too quickly (process log may have details)
  17. 人工智能学期心得体会
  18. 香港上网吃到饱,一天18港币!去香港手机/笔电上网请爱用 3 HK 的 3G 循环储值咭(卡)
  19. 小王利用计算机设计了一个计算程序,小王利用计算机设计了一个计算程序,输入和输出的数据如下表:那么,当输入数据是8时,输出的数据是[]A.B.C.D.-七年级数学...
  20. LINUX基础实验练习

热门文章

  1. 真的高品质吗?看声谱鉴别真假音质
  2. 使用docker方式搭建免费开源的境外商城网站
  3. 20年寒假实习面经(中科院自动化所、Momenta、百度大搜、字节跳动等)
  4. oracle怎么取绝对值,Oracle数值处理函数 (绝对值、取整...)
  5. DXC Technology将收购领先数字创新公司Luxoft
  6. dumpsys activity 相关命令解析
  7. 教你如何生一个漂亮宝宝
  8. jsf的初步使用(包括jsf框架的引入、用户登录、自定义表单验证、valueChangeEvent值变更事件处理做的级联下拉框)
  9. 微信小程序 pages的使用
  10. springmvc+logback 控制台打印mybatis执行的sql