151209 总结

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



你可能感兴趣的:(优化,乱搞,主席树,树套树)