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;
}