123789456ye

已AFO

JSOI2014

A 拼图

题面:Luogu
题解:根号分治?
显然最优策略就是连续一段白的放中间,其他的放两边
考虑到\(n*m<=10^5\)
于是我们分类讨论一下

  • \(n<=m\)
    枚举最终白色矩阵的上下为d,u
    如果一块拼图d行到u行全都为白就为I类,否则为II类
    于是最终的解就是I类放中间,左右放II类。因为左右不能一样所以还要记录次大值

  • \(n>m\)
    对于每个点,记录它往上的第一个黑点行数作为u, 它自身的行数为d
    剩下的同上
    复杂度:\(O(nm*\min(n,m))\)

codeA

B 宅男计划

题面:bzoj
题解:三分+贪心
可以发现一个显然的性质
就是你买外卖的次数和你能维持的天数大概是成一个单峰函数证明不会
于是我们三分峰值
然后找到这个次数后再贪心
首先把那些又贵又放不久的扔掉,可以用单调栈
然后从最便宜的开始往上贪心
code

C 骑士游戏

题面:bzoj
题解:最短路?
可以显然的写出一个dp方程,然而你会发现会有环
我们发现这个方程的形式和spfa的转移形式差不多
所以把所有点扔到队列里,初值设置魔法攻击的代价,跑最短路
如果这个点被更新了,则反图上与它相连的点都有可能更新,入队
codeC

D 支线剧情

题面:Luogu
题解:上下界最小费用流
\(<fr,to,flow_{min},flow_{max},cost>\)
对于每条边,连\(<u,v,1,inf,time>\)表示至少要走一次
其他的按照上下界的格式连边
还有为什么这道题dinic会锅啊!(死循环)
我查了半天最后把dinic改成EK就过了?
codeD

F 奇怪的计算器

题面:bzoj
题解:线段树
首先将这些值,因为不管怎么样都不会改变他们的大小关系
区间修改,如果最小的值小于下界就直接推平,上界同理
codeF

G 支线剧情2

题面:bzoj
题解:树形dp
\(f[i]\)表示这个点有存档,之后都不存档的最少代价

\[f[u]=\sum_{(u,v,w)\in E}{f[v]+siz[v]*w} \]

\(dp[u]\)表示这个点子树内有存档的最小代价
如果当前点存档,儿子也有一个存档则\(dp[u]+=dp[v]+deep[v]\)\(deep\)为从1到这个点的距离
否则直接转移(就是枚举一个最小值)
codeG

I 强连通图

题面:bzoj
题解:缩点
直接缩点就可以了
codeI

J 歌剧表演

题面:bzoj
题解:
用set维护不能分辨出来的一群人,相当于染色
具体看代码吧
codeJ

L 回文串

题面:bzoj
题解:manacher+树状数组
先跑一遍manacher
对于每一个询问,令\(l=2*l-1,r=2*r+1\)(因为插入了其他字符)
\(mid=\left\lfloor\frac{l+r}{2}\right\rfloor\)
所以\([l,mid]\)间的询问只会被\(l\)限制,\([mid+1,r]\)间的只会被\(r\)限制
于是\([l,mid]\)间的答案

\[\sum_{i=l}^{mid}\big[[i-p_i+1\geq l]p_i+[i-p_i+1<l](i-l+1)\big] \]

也就是回文串左边界没有超过\(l\)的直接计入答案
为什么这样计贡献?我想了很久才想出来
因为每一个点每被覆盖一次就有一个\([j,i]\)的字串,所以可以直接计长度为贡献
同理\([mid+1,r]\)间的答案

\[\sum_{i=mid+1}^r\big[[i+p_i-1\leq r]p_i+[i+p_i-1>r](r-i+1)\big] \]

两个分开,用树状数组离线处理
然后原来的\(Ans=\frac{ans-(r-l+2)}{2}\),因为加上了(r-l+2)个其他字符,并且每个回文串会被算两次
codeL

M 电信网络

题面:bzoj
题解:最大权闭合子图
原图上的边连inf,权值为正的从s到i连权值的边,否则从i到t连负权值的边
答案就是所有正权值之和减去最大流
codeM

N 打兔子

题面:bzoj
题解:dp
首先特判掉\(k\geq\left\lceil\frac{n}{2}\right\rceil\)
但是\(k=2,n=3\)时不行
有一个显然的性质:不会有相邻的两个洞都开枪
设一个\(dp[i][j][0/1]\)表示当前第\(i\)个洞,开了\(j\)枪,当前这个洞打/不打
破环为链,强制选第一个/最后一个/都不选即可

  • 如果下个洞不打,则这个洞可打可不打
  • 如果下个洞打,那么收益就是这个点不打的收益加上下个点的兔子数
  • 如果这个点打和下下个点打,那么下下个点的收益就是这个点打的收益加上后两个洞的兔子

实现看一下代码就知道了
codeN

O 序列维护

题面:bzoj
题解:线段树
区间加法,区间乘法
codeO

P学生选课

题面:bzoj
题解:二分+2-SAT
2-SAT的连边方式可能要稍微想一下
看代码吧
codeP

Q 矩形并

题面:bzoj
题解:扫描线+树状数组
就是要求所有矩形并的面积之和
于是变成交减去自身的面积
于是相当于矩形区间+1,区间求和
然而二维树状数组会爆掉
于是把一维换成扫描线
因为树状数组下标从1开始,所以整体平移2( \(\because x-1\geq 1\) )
注意要开long double
codeQ

codeA

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 100005
int sum[maxn],l[maxn],r[maxn],n,m,s,ans,up[maxn],a[maxn],w[maxn];
inline int id(int x,int y)
{
	if(x<1||y<1) return 0;
	return (y-1)*n+x;
}
inline int get(int x_1,int y_1,int x_2,int y_2)
{
	return sum[id(x_1-1,y_1-1)]+sum[id(x_2,y_2)]-sum[id(x_1-1,y_2)]-sum[id(x_2,y_1-1)];
}
void calc(int d,int u)
{
	int wid=0,tp=u-d+1;
	for(int i=1;i<=s;++i,wid=0)
		for(int j=l[i];j<=r[i];++j)
		{
			if(!get(d,j,u,j)) ++wid;
			else wid=0;
			ans=max(ans,tp*wid);
		}
	wid=0;
	pair<int,int> lmax,_lmax,rmax,_rmax;
	for(int i=1,maxl,maxr;i<=s;++i)
	{
		maxl=maxr=0;
		for(int j=l[i];j<=r[i];++j)
		{
			if(!get(d,j,u,j)) ++maxl;
			else break;
		}
		if(maxl==w[i])
		{
			wid+=w[i];
			continue;
		}
		for(int j=r[i];j>=l[i];--j)
		{
			if(!get(d,j,u,j)) ++maxr;
			else break;
		}
		if(maxl>lmax.first) lmax.first=maxl,lmax.second=i;
		else if(maxl>_lmax.first) _lmax.first=maxl,_lmax.second=i;
		if(maxr>rmax.first) rmax.first=maxr,rmax.second=i;
		else if(maxr>_rmax.first) _rmax.first=maxr,_rmax.second=i;
	}
	if(lmax.second!=rmax.second) ans=max(ans,tp*(lmax.first+wid+rmax.first));
	else
	{
		ans=max(ans,tp*(lmax.first+wid+_rmax.first));
		ans=max(ans,tp*(rmax.first+wid+_lmax.first));
	}
}
int main()
{
	int T;
	read(T);
	while(T--)
	{
		read(s),read(n);m=ans=0;
		for(int i=1;i<=s;++i)
		{
			read(w[i]);
			l[i]=m+1,m+=w[i],r[i]=m;
			for(int j=1;j<=n;++j)
				for(int k=l[i];k<=r[i];++k)
				{
					int& tp=a[id(j,k)];char c=getchar();
					while(!isdigit(c)) c=getchar();
					tp=c-'0';
				}
		}
		for(int i=1;i<=n;++i)
			for(int j=1;j<=m;++j)
				sum[id(i,j)]=sum[id(i-1,j)]+sum[id(i,j-1)]-sum[id(i-1,j-1)]+a[id(i,j)];
		if(n<m)
			for(int i=1;i<=n;++i)
				for(int j=i;j<=n;++j) calc(i,j);
		else
		{
			for(int j=1;j<=m;++j)
				for(int i=1,p=0;i<=n+1;++i)
					if(i>n||a[id(i,j)])
					{
						for(int k=p+1;k<i;++k) up[id(k,j)]=i-1;
						p=i;
					}
			for(int i=1;i<=n;++i)
				for(int j=1;j<=m;++j)
					if(!a[id(i,j)]) calc(i,up[id(i,j)]);
		}
		printf("%d\n",ans);
	}
	return 0;
}

top

B code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 205
#define ll long long
struct Food
{
	ll v,t;
	inline friend bool operator < (Food a,Food b)
		{
			return a.t<b.t;
		}
}a[maxn],sta[maxn];
int n,top;
ll m,f;
inline ll get(ll x)
{
	ll left=m-f*x,times=0,days=0,last;//剩余钱数,总天数,一次的天数,这一次买的东西能支持的天数
	if(left<0) return 0;
	for(int i=1;i<=n;++i)
	{
		last=min(a[i].t-days,left/(x*a[i].v));
		days+=last,times+=x*last,left-=last*x*a[i].v;
		if(days<a[i].t)//如果还是小于,则left那一项不够了(相当于没有买够这一项),就直接全买这一项
		{
			times+=left/a[i].v;
			break;
		}
	}
	return times;
}
int main()
{
	read(m),read(f),read(n);
	for(int i=1;i<=n;++i) read(a[i].v),read(a[i].t),++a[i].t;
	sort(a+1,a+n+1);
	for(int i=1;i<=n;++i)
	{
		while(top&&a[i].v<=sta[top].v) --top;
		sta[++top]=a[i];
	}
	n=top;
	for(int i=1;i<=n;++i) a[i]=sta[i];
	ll l=1,r=m/f+1,lm,rm,ans=0,ans1,ans2;
	while(l<=r)
	{
		lm=(l+l+r)/3,rm=(l+r+r)/3;
		ans1=get(lm),ans2=get(rm);
		if(ans1<ans2) l=lm+1,ans=max(ans,ans2);
		else r=rm-1,ans=max(ans,ans1);
	}
	if(l>1) ans=max(ans,get(l-1));//我的三分似乎有点锅,要把左右也算一下
	ans=max(ans,get(l+1));
	printf("%lld\n",ans);
	return 0;
}

top

C code

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 2000005
#define ll long long
struct Edge
{
	int fr,to;
}eg[maxn],eg_rev[maxn];
int head[maxn],head_rev[maxn],edgenum,vis[maxn],n;
inline void add(int fr,int to)
{
	eg[++edgenum]=(Edge){head[fr],to};
	eg_rev[edgenum]=(Edge){head_rev[to],fr};
	head[fr]=head_rev[to]=edgenum;
}
ll dis[maxn],s[maxn];
void spfa()
{
	queue<int> q;
	for(int i=1;i<=n;++i) q.push(i),vis[i]=1;
	while(!q.empty())
	{
		int id=q.front();
		q.pop(),vis[id]=0;
		ll res=s[id];
		for(int i=head[id];i;i=eg[i].fr)
			res+=dis[eg[i].to];
		if(res<dis[id])
		{
			dis[id]=res;
			for(int i=head_rev[id];i;i=eg_rev[i].fr)
				if(!vis[eg_rev[i].to]) vis[eg_rev[i].to]=1,q.push(eg_rev[i].to);
		}
	}
}
int main()
{
	read(n);
	int tp,num;
	for(int i=1;i<=n;++i)
	{
		read(s[i]),read(dis[i]),read(num);
		for(int j=1;j<=num;++j) read(tp),add(i,tp);
	}
	spfa();
	printf("%lld\n",dis[1]);
	return 0;
}

top

codeD

#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	x*=f;
}
#define maxn 100005
#define inf 0x3f3f3f3f
struct Edge
{
	int fr,to,val,cost;
}eg[maxn<<1];
int head[maxn],edgenum=1;
int dis[maxn],vis[maxn],lst[maxn],S,T;
int d[maxn],n;
inline void add(int fr,int to,int val,int cost)
{
	eg[++edgenum]=(Edge){head[fr],to,val,cost};
	head[fr]=edgenum;
}
inline void Add(int fr,int to,int val,int cost)
{
	add(fr,to,val,cost);
	add(to,fr,0,-cost);
}
bool bfs()
{
	for(int i=0;i<=n;++i) dis[i]=inf,lst[i]=0;
	queue<int> q;
	dis[S]=0;q.push(S);
	int tp;
	while(!q.empty())
	{
		tp=q.front();q.pop();
		vis[tp]=0;
		for(int i=head[tp];~i;i=eg[i].fr)
			if(dis[eg[i].to]>dis[tp]+eg[i].cost&&eg[i].val)
			{
				dis[eg[i].to]=dis[tp]+eg[i].cost;
				lst[eg[i].to]=i;
				if(!vis[eg[i].to]) q.push(eg[i].to),vis[eg[i].to]=1;
			}
	}
	return lst[T]!=0;
}
int main()
{
	//freopen("test.in","r",stdin);
	memset(head,-1,sizeof(head));
	read(n);
	S=0,T=n+2;
	int tp,x,y,ans=0;
	for(int i=1;i<=n;++i)
	{
		read(tp);
		for(int j=1;j<=tp;++j)
		{
			read(x),read(y);
			--d[i],++d[x];ans+=y;
			Add(i,x,inf-1,y);
		}
	}
	for(int i=1;i<=n;++i) Add(i,n+1,inf,0);
	Add(n+1,1,inf,0);
	for(int i=1;i<=n+1;++i)
	{
		if(d[i]>0) Add(S,i,d[i],0);
		else if(d[i]<0) Add(i,T,-d[i],0);
	}
	n+=2;
	while(bfs())
	{
		int f=inf;
		for(int i=lst[T];i;i=lst[eg[i^1].to]) f=min(f,eg[i].val);
		for(int i=lst[T];i;i=lst[eg[i^1].to]) eg[i].val-=f,eg[i^1].val+=f;
		ans+=dis[T]*f;
	}
	printf("%d\n",ans);
	return 0;
}

top

F code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 200005
#define ll long long
struct OP
{
	int type;ll val;
}q[maxn];
pair<int,int> a[maxn];
struct Node
{
	int l,r;
	ll ptag,mtag,ptag2,mn,mx;
}t[maxn<<2];
#define ls rt<<1
#define rs rt<<1|1
ll L,R,ans[maxn];
inline void pushup(const int& rt)
{
	t[rt].mx=t[rs].mx,t[rt].mn=t[ls].mn;
}
inline void modify(const int& rt,const ll& ptag,const ll& ptag2,const ll& mtag)
{
	t[rt].mtag*=mtag,t[rt].ptag=t[rt].ptag*mtag+ptag,t[rt].ptag2=t[rt].ptag2*mtag+ptag2;
	t[rt].mn=t[rt].mn*mtag+a[t[rt].l].first*ptag2+ptag;
	t[rt].mx=t[rt].mx*mtag+a[t[rt].r].first*ptag2+ptag;
}
inline void pushdown(const int& rt)
{
	modify(ls,t[rt].ptag,t[rt].ptag2,t[rt].mtag);
	modify(rs,t[rt].ptag,t[rt].ptag2,t[rt].mtag);
	t[rt].ptag=t[rt].ptag2=0,t[rt].mtag=1;
}
void build(const int& rt,const int& l,const int& r)
{
	t[rt].mtag=1,t[rt].l=l,t[rt].r=r;
	if(l==r)
	{
		t[rt].mx=t[rt].mn=a[l].first;
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(rt);
}
void pushmin(const int& rt)
{
	if(t[rt].l==t[rt].r) return modify(rt,L,0,0);
	pushdown(rt);
	if(t[rs].mn<L) modify(ls,L,0,0),pushmin(rs);
	else pushmin(ls);
	pushup(rt);
}
void pushmax(const int& rt)
{
	if(t[rt].l==t[rt].r) return modify(rt,R,0,0);
	pushdown(rt);
	if(t[ls].mx>R) modify(rs,R,0,0),pushmax(ls);
	else pushmax(rs);
	pushup(rt);
}
void dfs(const int& rt)
{
	if(t[rt].l==t[rt].r)
	{
		ans[a[t[rt].l].second]=t[rt].mn;
		return;
	}
	pushdown(rt);
	dfs(ls),dfs(rs);
}
int id[256];
int main()
{
	//file("test");
	int n,m;char op[2];
	id['+']=0,id['-']=1,id['*']=2,id['@']=3;
	read(n),read(L),read(R);
	for(int i=1;i<=n;++i)
	{
		scanf("%s",op);
		q[i].type=id[op[0]],read(q[i].val);
	}
	read(m);
	for(int i=1;i<=m;++i) read(a[i].first),a[i].second=i;
	sort(a+1,a+m+1);
	build(1,1,m);
	for(int i=1;i<=n;++i)
	{
		if(q[i].type==0) modify(1,q[i].val,0,1);
		else if(q[i].type==1) modify(1,-q[i].val,0,1);
		else if(q[i].type==2) modify(1,0,0,q[i].val);
		else modify(1,0,q[i].val,1);
		if(t[1].mn<L) pushmin(1);
		if(t[1].mx>R) pushmax(1);
	}
	dfs(1);
	for(int i=1;i<=m;++i) printf("%lld\n",ans[i]);
	return 0;
}

top

G code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 1000005
#define ll long long
struct Edge
{
	int fr,to,val;
}eg[maxn<<1];
int head[maxn],edgenum;
inline void add(int fr,int to,int val)
{
	eg[++edgenum]=(Edge){head[fr],to,val};
	head[fr]=edgenum;
}
ll f[maxn],dp[maxn],siz[maxn];
void dfs(int rt,ll dis)
{
	if(!head[rt])
	{
		siz[rt]=1;
		return;
	}
	ll tmp=0;
	for(int i=head[rt];i;i=eg[i].fr)
	{
		dfs(eg[i].to,eg[i].val+dis);
		siz[rt]+=siz[eg[i].to];
		f[rt]+=f[eg[i].to]+1ll*siz[eg[i].to]*eg[i].val;
		tmp+=min(f[eg[i].to]+1ll*siz[eg[i].to]*eg[i].val,dp[eg[i].to]+dis+eg[i].val);
	}
	dp[rt]=f[rt];
	for(int i=head[rt];i;i=eg[i].fr)
		dp[rt]=min(dp[rt],tmp-min(f[eg[i].to]+1ll*siz[eg[i].to]*eg[i].val,dp[eg[i].to]+dis+eg[i].val)+dp[eg[i].to]+eg[i].val);
}
int main()
{
	int n,k,a,b;
	read(n);
	for(int i=1;i<=n;++i)
	{
		read(k);
		for(int j=1;j<=k;++j)
			read(a),read(b),add(i,a,b);
	}
	dfs(1,0);
	printf("%lld\n",dp[1]);
	return 0;
}

top

I code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 1000005
struct Edge
{
	int fr,to;
}eg[maxn<<1];
int head[maxn],edgenum;
inline void add(int fr,int to)
{
	eg[++edgenum]=(Edge){head[fr],to};
	head[fr]=edgenum;
}
int vis[maxn],dfn[maxn],low[maxn],dfn_clock,col[maxn],siz,colnum,ans;
int invis[maxn],outvis[maxn];
stack<int> s;
void Tarjan(int rt)
{
	low[rt]=dfn[rt]=++dfn_clock;
	s.push(rt);
	vis[rt]=1;
	for(int i=head[rt];i;i=eg[i].fr)
	{
#define to eg[i].to
		if(!dfn[to]) Tarjan(to),low[rt]=min(low[rt],low[to]);
		else if(vis[to]) low[rt]=min(low[rt],dfn[to]);
#undef to
	}
	if(low[rt]==dfn[rt])
	{
		++colnum;
		siz=0;
		while(s.top()!=rt)
		{
			int tp=s.top();
			s.pop();
			col[tp]=colnum;
			++siz;
			vis[tp]=0;
		}
		s.pop();
		col[rt]=colnum;
		++siz;
		vis[rt]=0;
		ans=max(ans,siz);
	}
}
int main()
{
	int n,m,x,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i) scanf("%d%d",&x,&y),add(x,y);
	for(int i=1;i<=n;++i)
		if(!dfn[i]) Tarjan(i);
	printf("%d\n",ans);
	for(int i=1;i<=n;++i)
		for(int j=head[i];j;j=eg[j].fr)
			if(col[i]!=col[eg[j].to])
				invis[col[eg[j].to]]=1,outvis[col[i]]=1;
	int indeg=0,outdeg=0;
	for(int i=1;i<=colnum;++i)
	{
		if(!invis[i]) ++indeg;
		if(!outvis[i]) ++outdeg;
	}
	printf("%d\n",max(indeg,outdeg));//注意不要特判0(我也不知道为什么)
	return 0;
}

top

J code

#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
	x = 0; char c = getchar();
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
#define maxn 100005
set<int> s[maxn];
int a[maxn], col[maxn], ans[maxn], cnt, n, m;
inline bool cmp(int a, int b)
{
	return col[a] < col[b];
}
int main()
{
	read(n), read(m);
	int k;
	for (int i = 1; i <= n; ++i) s[0].insert(i);
	for (int i = 1; i <= m; ++i)
	{
		read(k);
		for (int j = 1; j <= k; ++j) read(a[j]);
		sort(a + 1, a + k + 1, cmp);
		for (int l = 1, r; l <= k; l = r + 1)
		{
			r = l;
			while (r < k && col[a[r + 1]] == col[a[l]]) ++r;
			if (s[col[a[l]]].size() == r - l + 1) continue;
			int now = col[a[l]]; ++cnt;
			for (int j = l; j <= r; ++j)
				s[now].erase(a[j]), col[a[j]] = cnt, s[cnt].insert(a[j]);
			if (s[now].size() == 1 && !ans[*s[now].begin()])
				ans[*s[now].begin()] = i;
			if (s[cnt].size() == 1 && !ans[*s[cnt].begin()])
				ans[*s[cnt].begin()] = i;
		}
	}
	for (int i = 1; i <= n; ++i) printf("%d ", ans[i]);
	//for (int i = 1; i <= n; ++i) printf("%d%c", ans[i], "\n"[i == n]);
	return 0;
}

top

codeL

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 300005
#define ll long long
ll ans[maxn];
int p[maxn],n;
char s[maxn];
struct Bit
{
	ll c[maxn];
	inline int lowbit(const int& x)
		{
			return x&(-x);
		}
	inline void update(const int& pos,const ll& val)
		{
			for(int i=pos;i<=n;i+=lowbit(i)) c[i]+=val;
		}
	inline ll query(const int& pos)
		{
			ll ans=0;
			for(int i=pos;i;i-=lowbit(i)) ans+=c[i];
			return ans;
		}
	inline void init()
		{
			memset(c,0,sizeof(c));
		}
}A,B,C;
struct Query
{
	int mid,id;
};
vector<Query> L[maxn],R[maxn];
vector<Query>::iterator it;
vector<int> ve[maxn];
vector<int>::iterator _it;
inline void get(char* s,int* p)
{
	char c=getchar();
	s[0]='~',s[n=1]='#';
	while(!isalpha(c)) c=getchar();
	while(isalpha(c)) s[++n]=c,s[++n]='#',c=getchar();
	for(int i=1,r=0,mid=0;i<=n;++i)
	{
		p[i]=min(p[(mid<<1)-i],r-i+1);
		while(s[i-p[i]]==s[i+p[i]]) ++p[i];
		if(i+p[i]>r) r=i+p[i]-1,mid=r;
	}
}
inline void init()
{
	A.init(),B.init(),C.init();
	for(int i=1;i<=n;++i) ve[i].clear();
}
#define mid (*it).mid
#define id (*it).id
#define tp (*_it)
//A维护满足第一个条件的p[i]前缀和
//B维护符合第二个条件的i的前缀和,C维护符合第二个条件的“1”的前缀和
void solvel()
{
	for(int i=1;i<=n;++i)//ve[i]存储以i为左边界的所有mid,一开始所有左边界都大于等于1
		ve[i-p[i]+1].push_back(i),A.update(i,p[i]);
	for(int i=1;i<=n;++i)//枚举左边界
	{
		for(it=L[i].begin();it!=L[i].end();++it)
			ans[id]+=A.query(mid)+B.query(mid)-C.query(mid)*(i-1);
		for(_it=ve[i].begin();_it!=ve[i].end();++_it)//从l变为l+1需要更新的东西
			A.update(tp,-p[tp]),B.update(tp,tp),C.update(tp,1);
	    B.update(i,-i),C.update(i,-1);//去掉等于l的贡献
	}
}
void solver()
{
	for(int i=1;i<=n;++i)
		ve[i+p[i]-1].push_back(i),A.update(n+1-i,p[i]);
	for(int i=n;i;--i)
	{
		for(it=R[i].begin();it!=R[i].end();++it)
			ans[id]+=A.query(n+1-mid)-B.query(n+1-mid)+C.query(n+1-mid)*(i+1);
		for(_it=ve[i].begin();_it!=ve[i].end();++_it)
			A.update(n+1-tp,-p[tp]),B.update(n+1-tp,tp),C.update(n+1-tp,1);
		B.update(n+1-i,-i),C.update(n+1-i,-1);
	}
}
#undef mid
#undef id
#undef tp
int main()
{
	get(s,p);
	int q,l,r,mid;
	read(q);
	for(int i=1;i<=q;++i)
	{
		read(l),read(r);
		ans[i]=l-r-2;
		mid=l+r,l=(l<<1)-1,r=(r<<1)+1;
		L[l].push_back((Query){mid,i});
		R[r].push_back((Query){mid+1,i});
	}
	solvel();
	init(),solver();
	for(int i=1;i<=q;++i) printf("%lld\n",ans[i]>>1);
	return 0;
}

top

M code

#include<bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();int f=1;
	while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	x*=f;
}
#define maxn 505
#define inf 0x3f3f3f3f
struct Edge
{
	int fr,to,val;
}eg[maxn*maxn*2];
int head[maxn],edgenum=1,n,m;
inline void add(int fr,int to,int val)
{
	eg[++edgenum]=(Edge){head[fr],to,val};
	head[fr]=edgenum;
}
int deep[maxn],gap[maxn],cur[maxn],s,t,maxflow;
void bfs()
{
	queue<int> q;
	for(int i=0;i<=n;++i) deep[i]=-1,gap[i]=0;
	deep[t]=0;gap[0]=1;
	q.push(t);
	while(!q.empty())
	{
		int tmp=q.front();q.pop();
		for(int i=head[tmp];i;i=eg[i].fr)
			if(deep[eg[i].to]==-1)
			{
				q.push(eg[i].to);
				deep[eg[i].to]=deep[tmp]+1;
				++gap[deep[eg[i].to]];
			}
	}
}
int dfs(int now,int flow)
{
	if(now==t)
	{
		maxflow+=flow;
		return flow;
	}
	int tmpflow=0,used=0;
	for(int i=cur[now];i;i=eg[i].fr)
	{
		cur[now]=i;
		if(deep[now]==deep[eg[i].to]+1&&eg[i].val)
		{
			if(tmpflow=dfs(eg[i].to,min(flow-used,eg[i].val)))
			{
				used+=tmpflow;
				eg[i].val-=tmpflow;
				eg[i^1].val+=tmpflow;
			}
			if(used==flow) return used;
		}
	}
	if(!--gap[deep[now]]) deep[s]=n+1;
	++gap[++deep[now]];
	return used;
}
void ISAP()
{
	bfs();
	while(deep[s]<n) memcpy(cur,head,sizeof(head)),dfs(s,0x3f3f3f3f);
}
struct Node
{
	int x,y,r,v;
}o[maxn];
inline int dis(Node a,Node b)
{
	return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int main()
{
	read(n);
	s=0,t=n+1;
	for(int i=1;i<=n;++i)
		read(o[i].x),read(o[i].y),read(o[i].r),read(o[i].v);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
		{
			if(i==j) continue;
			if(dis(o[i],o[j])<=o[i].r*o[i].r) add(i,j,inf),add(j,i,0);
		}
	int ans=0;
	for(int i=1;i<=n;++i)
	{
		if(o[i].v>0) add(s,i,o[i].v),add(i,s,0),ans+=o[i].v;
		else add(i,t,-o[i].v),add(t,i,0);
	}
	ISAP();
	printf("%d\n",ans-maxflow);
	return 0;
}

top

codeN

#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 4005
int a[maxn],n,k;
int ans,dp[maxn][maxn][2];
inline void cmax(int& x,int y)
{
	if(y>x) x=y;
}
void solve()
{
	for(int i=1;i<n;++i)
		for(int j=0;j<=k;++j)
		{
			cmax(dp[i+1][j][0],max(dp[i][j][0],dp[i][j][1]));
			if(j<k) cmax(dp[i+1][j+1][1],dp[i][j][0]+a[i+1]);
			if(i+2<=n&&j<k) cmax(dp[i+2][j+1][1],dp[i][j][1]+a[i+1]+a[i+2]);
		}
	cmax(ans,dp[n][k][0]);
}
void calc()
{
	int tp=a[n];a[n-1]+=tp,a[n]=0;
	memset(dp,0xcf,sizeof(dp));
	dp[1][1][1]=a[1];solve();
	a[n]=tp,a[n-1]-=tp;
}
int main()
{
	read(n),read(k);
	for(int i=1;i<=n;++i) read(a[i]);
	if(n==3&&k==2)
		sort(a+1,a+n+1),ans=a[2]+a[3];
	else if(k>=((n+1)>>1))
		for(int i=1;i<=n;++i) ans+=a[i];
	else
	{
		memset(dp,0xcf,sizeof(dp));
		dp[1][0][0]=0;solve();
		calc();
		reverse(a+1,a+n+1);
		calc();
	}
	printf("%d\n",ans);
	return 0;
}

top

O code

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 200005
#define ll long long
struct Node
{
	int l,r;
	ll val,ptag,mtag;
}t[maxn<<2];
#define ls rt<<1
#define rs rt<<1|1
ll p,a[maxn];
inline void pushup(const int& rt)
{
	t[rt].val=(t[ls].val+t[rs].val)%p;
}
inline int len(const int& rt)
{
	return t[rt].r-t[rt].l+1;
}
inline void modify(int rt,ll ptag,ll mtag)
{
	if(ptag==0&&mtag==1) return;
	t[rt].val=(t[rt].val*mtag+ptag*len(rt))%p;
	t[rt].ptag=(t[rt].ptag*mtag+ptag)%p;
	t[rt].mtag=t[rt].mtag*mtag%p;
}
inline void pushdown(const int& rt)
{
	if(t[rt].ptag==0&&t[rt].mtag==1) return;
	modify(ls,t[rt].ptag,t[rt].mtag);
	modify(rs,t[rt].ptag,t[rt].mtag);
	t[rt].ptag=0,t[rt].mtag=1;
}
inline void build(int rt,int l,int r)
{
	t[rt].mtag=1,t[rt].l=l,t[rt].r=r;
	if(l==r)
	{
		t[rt].val=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(rt);
}
inline void update(int rt,int l,int r,int fr,int to,ll ptag,ll mtag)
{
	if(fr<=l&&to>=r) return modify(rt,ptag,mtag);
	int mid=(l+r)>>1;
	pushdown(rt);
	if(fr<=mid) update(ls,l,mid,fr,to,ptag,mtag);
	if(to>mid) update(rs,mid+1,r,fr,to,ptag,mtag);
	pushup(rt);
}
inline ll query(int rt,int l,int r,int fr,int to)
{
	if(fr<=l&&to>=r) return t[rt].val;
	int mid=(l+r)>>1;ll ans=0;
	pushdown(rt);
	if(fr<=mid) ans=query(ls,l,mid,fr,to);
	if(to>mid) ans+=query(rs,mid+1,r,fr,to);
	return ans%p;
}
inline void print(int n)
{
	for(int i=1;i<=n;++i) printf("%lld ",query(1,1,n,i,i));
	puts(" ");
}
int main()
{
	//file("test");
	int n,m;
	read(n),read(p);
	for(int i=1;i<=n;++i) read(a[i]),a[i]%=p;
	build(1,1,n);
	read(m);
	int op,x,y,z;
	for(int i=1;i<=m;++i)
	{
		read(op),read(x),read(y);
		if(op==3) printf("%lld\n",query(1,1,n,x,y));
		else read(z),update(1,1,n,x,y,op==2?z:0,op==1?z:1);
	}
	return 0;
}

top

codeP

#include<bits/stdc++.h>
using namespace std;
#define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout);
template<typename T>
inline void read(T& x)
{
	x=0;char c=getchar();
	while(!isdigit(c)) c=getchar();
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
}
#define maxn 2005
struct Edge
{
	int fr,to;
}eg[maxn*maxn*2];
int head[maxn],edgenum;
inline void add(int fr,int to)
{
	eg[++edgenum]=(Edge){head[fr],to};
	head[fr]=edgenum;
}
stack<int> s;
int dfn[maxn],low[maxn],dfn_clock,vis[maxn],col[maxn],colnum;
void Tarjan(int rt)
{
	dfn[rt]=low[rt]=++dfn_clock;
	s.push(rt);vis[rt]=1;
	for(int i=head[rt];i;i=eg[i].fr)
	{
		if(!dfn[eg[i].to]) Tarjan(eg[i].to),low[rt]=min(low[rt],low[eg[i].to]);
		else if(vis[eg[i].to]) low[rt]=min(low[rt],dfn[eg[i].to]);
	}
	if(low[rt]==dfn[rt])
	{
		int tp;
		++colnum;
		while(true)
		{
			tp=s.top(),s.pop();
			col[tp]=colnum,vis[tp]=0;
			if(tp==rt) break;
		}
	}
}
int n,rk[maxn>>1][maxn>>1],x[maxn],y[maxn];
bool check(int lim)
{
	memset(head,0,sizeof(head));
	memset(vis,0,sizeof(vis));
	memset(dfn,0,sizeof(dfn));
	colnum=dfn_clock=edgenum=0;
	int tp;
	for(int i=1;i<=n;++i)
		for(int j=lim+1;j<n;++j)
		{
			tp=rk[i][j];
		    if(x[i]==x[tp]) add(i,tp+n),add(tp,i+n);
			if(x[i]==y[tp]) add(i,tp),add(tp+n,i+n);
			if(y[i]==x[tp]) add(i+n,tp+n),add(tp,i);
			if(y[i]==y[tp]) add(i+n,tp),add(tp+n,i);
		}
	for(int i=1;i<=(n<<1);++i)
		if(!dfn[i]) Tarjan(i);
	for(int i=1;i<=n;++i)
		if(col[i]==col[i+n]) return false;
	return true;
}
int main()
{
	read(n);
	int tp;
	for(int i=1;i<=n;++i)
	{
		read(tp);
		x[i]=(tp==0)?1:0;
		y[i]=(tp==2)?1:2;
		for(int j=1;j<n;++j) read(rk[i][j]);
	}
	int l=1,r=n-1,mid;
	while(l<r)
	{
		mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	printf("%d\n",l);
	return 0;
}

top

codeQ

#include<bits/stdc++.h>
using namespace std;

inline void read(int& x)
{
	x = 0; char c = getchar();
	while (!isdigit(c)) c = getchar();
	while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
#define maxn 200005
#define ll long double
struct Line
{
	int x, l, r, v, op;
	inline friend bool operator < (Line a, Line b)
	{
		if (a.x != b.x) return a.x < b.x;
		if (a.op != b.op) return a.op < b.op;
		return a.v < b.v;
	}
}q[maxn << 2];

struct Bittree
{
#define lim 2000000
	ll c[lim + 5];
	inline int lowbit(int& x)
	{
		return x & (-x);
	}
	void update(int pos, ll v)
	{
		for (int i = pos; i <= lim; i += lowbit(i)) c[i] += v;
	}
	ll query(int pos)
	{
		ll ans = 0;
		for (int i = pos; i; i -= lowbit(i)) ans += c[i];
		return ans;
	}
#undef lim
}A, B, C, D;
inline void modify(int x, int y, int v)
{
	A.update(y, v), B.update(y, x * v), C.update(y, y * v), D.update(y, (ll)x * y * v);
}
inline ll query(int x, int y)
{
	return A.query(y) * (x + 1) * (y + 1) - B.query(y) * (y + 1) - C.query(y) * (x + 1) + D.query(y);
}
int cnt, n;
ll ans;
int main()
{
	read(n);
	int x, y, a, b;
	for (int i = 1; i <= n; ++i)
	{
		read(x), read(y), read(a), read(b);
		x += 2, y += 2;
		q[++cnt] = { x,y,y + b - 1,1 ,0 };
		q[++cnt] = { x + a,y,y + b - 1,-1,0 };
		q[++cnt] = { x - 1,y,y + b - 1,-1,1 };
		q[++cnt] = { x + a - 1,y,y + b - 1,1,1 };
		ans -= 1ll * a * b;
	}
	sort(q + 1, q + cnt + 1);
	for (int i = 1; i <= cnt; ++i)
	{
		if (q[i].op)
			ans += q[i].v * (query(q[i].x, q[i].r) - query(q[i].x, q[i].l - 1));
		else
			modify(q[i].x, q[i].l, q[i].v), modify(q[i].x, q[i].r + 1, -q[i].v);
	}
	printf("%.8Lf\n", ans / n / (n - 1));
	return 0;
}

top

posted @ 2020-02-05 11:04  123789456ye  阅读(184)  评论(0编辑  收藏  举报