T1
做过的。网络流+离散化,实现耗了很久
对拍+std 写了一个小时= =果然离散化就是恶心(还是自己太弱了)
T2
暴力搜吧
各种启发式搞了30分
然而正解是状压DP
T3
我们可以把序列切割搞这个问题
每个块可以维护一个平衡树,整体用一个块状链表套起来
然后yjq说可以二分(卧槽)%yjq
YYY说可以线段树套线段树(%yyy)
然后被卡常数了 70
100+30+70,果然太弱
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #define inf 1000000000 #define o(e) ((((e)-1)^1)+1) using namespace std; inline void splay(int &v) { v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } struct Edge { int to,len,next; }edge[5000000]; int first[1002],size; int deep[1002]; int dl[1002]; int a[301],b[301],c[301]; int p[1002],tot; inline void addedge(int x,int y,int z) { //if(z!=0)fprintf(stderr,"%d %d %d\n",x,y,z); size++; edge[size].to=y; edge[size].next=first[x]; first[x]=size; edge[size].len=z; } bool bfs(int s,int t) { memset(deep,-1,sizeof deep); int head=0,tail=1; dl[1]=s; deep[s]=0; while(head!=tail) { head++; for(int u=first[dl[head]];u;u=edge[u].next) { if(edge[u].len>0 && deep[edge[u].to]==-1) { dl[++tail]=edge[u].to; deep[edge[u].to]=deep[dl[head]]+1; } } } if(deep[t]==-1)return false; return true; } int dfs(int now,int flow,int t) { if(now==t)return flow; int F=0; for(int u=first[now];u&&flow>0;u=edge[u].next) { if(edge[u].len>0 && deep[edge[u].to]-deep[now]==1) { int ret=dfs(edge[u].to,min(edge[u].len,flow),t); F+=ret; edge[u].len-=ret; edge[o(u)].len+=ret; flow-=ret; } } if(!F)deep[now]=-5; return F; } int maxflow(int s,int t) { int ret=0; while(bfs(s,t)) ret+=dfs(s,inf,t); return ret; } int n,m; int main() { freopen("arrange.in","r",stdin); freopen("arrange.out","w",stdout); int T;splay(T); while(T--) { splay(n),splay(m);int sig=0;tot=0; size=0;memset(first,0,sizeof first); for(int i=1;i<=n;i++) { splay(a[i]),splay(b[i]),splay(c[i]); b[i]+=2,c[i]+=2; p[++tot]=b[i],p[++tot]=c[i]; sig+=a[i]; } sort(p+1,p+tot+1),unique(p+1,p+tot+1); tot=0;while(p[tot]<p[tot+1])tot++; for(int i=1;i<=n;i++) { int now; for(now=1;;now++)if(p[now]==b[i])break; while(p[now]!=c[i]) { addedge(i,now+300,p[now+1]-p[now]); addedge(now+300,i,0);now++; } addedge(0,i,a[i]); addedge(i,0,0); } for(int i=1;i<=tot-1;i++) { addedge(i+300,1001,(p[i+1]-p[i])*m); addedge(1001,i+300,0); } maxflow(0,1001)==sig?puts("Yes"):puts("No"); } }
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #define inf 1000000000 using namespace std; inline void splay(int &v) { v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } int n,m; int mp[11][11]; bool used[11][11]; bool vis[11][11]; double cost[11][11]; int ans=inf; struct node { double cost; int tx,ty; }; bool comp(const node &a,const node &b) { return a.cost<b.cost; } void dfs(int x,int y,int sum) { if(clock()>=1900)return; vis[x][y]=true; ans=min(ans,sum); node nodes[100];int tot=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(used[i][j]||vis[i][j])continue; if(vis[i-1][j]||vis[i][j-1]||vis[i+1][j]||vis[i][j+1]) nodes[++tot]=(node){cost[i][j],i,j}; } } sort(nodes+1,nodes+tot+1,comp); for(int i=1;i<=tot;i++) { dfs(nodes[i].tx,nodes[i].ty,sum+mp[nodes[i].tx][nodes[i].ty]); } vis[x][y]=false; } void maincost() { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int l=1;l<=n;l++) { for(int r=1;r<=m;r++) { if(i==l && j==r)continue; cost[l][r]+=mp[i][j]*5/(abs(i-l)+abs(j-r)); } } } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cost[i][j]+=mp[i][j]*2; } } } int main() { freopen("cheapest.in","r",stdin); freopen("cheapest.out","w",stdout); splay(n),splay(m);bool flag=false; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { splay(mp[i][j]); if(mp[i][j]<0)flag=true; } } maincost(); /*for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { printf("%d ",cost[i][j]); } printf("\n"); } return 0;*/ if(!flag)puts("0"),exit(0); for(int T=1;T<=n*m;T++) { int tx,ty; double tmp=inf; for(int i=n;i>=1;i--) { for(int j=m;j>=1;j--) { if(mp[i][j]>0)continue; //dfs(i,j,mp[i][j]); if(cost[i][j]<tmp)tmp=cost[i][j],tx=i,ty=j; } } used[tx][ty]=true; dfs(tx,ty,mp[tx][ty]); if(clock()>=1950)break; } cout<<ans<<endl; }
//Copyright(c)2015 liuchenrui #include<cstdio> #include<ctime> #include<iostream> #include<algorithm> #include<cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define ll long long #define inf 1000000000 /*************** n*sqrt(n)*log(n) ***************/ //using namespace std; inline void splay(int &v) { v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } int P; int ls[6000000],rs[6000000],fa[6000000]; int size[6000000],num[6000000],val[6000000]; int ass[300010],sum[300010]; int a[300010],b[300010],r[300010]; int nodecount; int root; int tot; int m; ll ans=0; void merge(int s,int mid,int t) { int k=s,i=s,j=mid+1; while(i<=mid && j<=t) if(a[i]>a[j])r[k++]=a[j++],ans+=mid-i+1; else r[k++]=a[i++]; while(i<=mid)r[k++]=a[i++]; while(j<=t)r[k++]=a[j++]; for(i=s;i<=t;i++)a[i]=r[i]; } void mergesort(int l,int r) { if(l==r)return; int mid=l+r>>1; mergesort(l,mid); mergesort(mid+1,r); merge(l,mid,r); } void update(int now) { size[now]=size[ls[now]]+size[rs[now]]+num[now]; } void left_rotate(int now) { if(now==root)return; int f=fa[now],ff=fa[fa[now]],b=ls[now]; if(f==root) { root=now; ls[now]=f;fa[f]=now;rs[f]=b; if(b!=0)fa[b]=f; } else { fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now; ls[now]=f;fa[f]=now;rs[f]=b; if(b!=0)fa[b]=f; } update(f),update(now); } void right_rotate(int now) { if(now==root)return; int f=fa[now],ff=fa[fa[now]],b=rs[now]; if(f==root) { root=now; rs[now]=f;fa[f]=now;ls[f]=b; if(b!=0)fa[b]=f; } else { fa[now]=ff;if(ls[ff]==f)ls[ff]=now;else rs[ff]=now; rs[now]=f;fa[f]=now;ls[f]=b; if(b!=0)fa[b]=f; } update(f),update(now); } int newnode() { ++tot; size[tot]=1; num[tot]=1; return tot; } void insert(int now,int x) { if(x==val[now]) { num[now]++; update(now); return; } if(x<val[now]) { if(ls[now]!=0)insert(ls[now],x); else { ls[now]=newnode(); fa[tot]=now; val[tot]=x; } //if(priority[now]>priority[ls[now]]) //if(!(rand()&4)) if(false) right_rotate(ls[now]); } else { if(rs[now]!=0)insert(rs[now],x); else { rs[now]=newnode(); fa[tot]=now; val[tot]=x; } //if(priority[now]>priority[rs[now]]) //if(!(rand()&4)) if(false) left_rotate(rs[now]); } update(now); } int calc(int now,int x) { if(now==0)return 0; if(x<val[now])return calc(ls[now],x); if(x==val[now])return size[ls[now]]; return calc(rs[now],x)+size[ls[now]]+num[now]; } int n; int rootcnt; void build(int l,int r,int &ass) { ass=++tot; val[ass]=inf+1; val[++tot]=-inf-1; ls[ass]=ass+1;fa[ass+1]=ass; size[ass]=2;size[ass+1]=1; num[ass]=num[ass+1]=1; root=ass; for(int i=l;i<=r;i++) { insert(ass,a[i]); ass=root; } } int fuck(int x) { int now=1;int ret=0; for(int i=1;now<=n;now+=P,i++) { if(now+P-1>=x)break; else ret+=i+P-now-calc(ass[i],a[x]+1)+1; } for(int i=now;i<=min(now+P-1,n);i++) { if(i<x && a[i]>a[x])ret++; if(i>x && a[i]<a[x])ret++; } now+=P; for(int i=now/P+1;now<=n;now+=P,i++) { ret+=calc(ass[i],a[x])-1; } return ret; } #include<math.h> int main() { freopen("counting.in","r",stdin); freopen("counting.out","w",stdout); srand(time(0)); splay(n);P=(int)sqrt(n); for(int i=1;i<=n;i++) { splay(a[i]);b[i]=a[i]; } mergesort(1,n); //std::cerr<<clock()<<std::endl; for(int i=1;i<=n;i++)a[i]=b[i]; for(int i=1;i<=min(i+P-1,n);i+=P) { build(i,min(i+P-1,n),ass[++rootcnt]); } splay(m); //std::cerr<<clock()<<std::endl; for(int T=1;T<=m;T++) { int x,y; splay(x),splay(y); int l=fuck(x); a[x]=y; for(int i=1,now=1;i<=n;i+=P,now++) { if(i+P-1>=x) { build(i,min(i+P-1,n),ass[now]); break; } } int r=fuck(x); ans+=(ll)(r-l); printf("%I64d\n",ans); // if(T%100==1)std::cerr<<T/100<<":"<<clock()<<std::endl; } //std::cerr<<clock()<<std::endl; //std::cerr<<tot<<std::endl; }