zoukankan      html  css  js  c++  java
  • Codeforces Round #546 Div. 2

      D:从后往前考虑每个人,显然如果能移到最后一个人后方就应该立即移动,否则移不移没什么影响。链表暴力模拟这个过程即可。容易发现复杂度是线性的(判断两人间是否有边可能需要带log)。当然事实上根本不需要链表,直接检查其对后方未删除点的出度之和即可。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define ll long long
    #define N 300010
    #define M 500010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,a[N],p[N],t,nxt[N],pre[N],degree[N],ans;
    map<int,int> f[N];
    void del(int k)
    {
    	nxt[pre[k]]=nxt[k];
    	pre[nxt[k]]=pre[k];
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<=m;i++)
    	{
    		int x=read(),y=read();
    		f[x][y]=1;degree[x]++;
    	}
    	for (int i=0;i<n;i++) nxt[i]=i+1;
    	for (int i=1;i<=n;i++) pre[i]=i-1;
    	for (int i=n-1;i>=1;i--)
    	{
    		int x=a[i];
    		if (f[x][a[n]])
    		{
    			if (n-i-ans>degree[x]) continue;
    			int u=i;
    			while (u!=n)
    			{
    				if (!f[x][a[nxt[u]]]) break;
    				u=nxt[u];
    			}
    			if (u==n)
    			{
    				ans++;
    				del(i);
    			}
    		}
    	}
    	cout<<ans;
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      E:分块,每块维护第一个数和块的总和。注意到每次修改影响的是一段连续区间,于是根据块的第一个数暴力找到最后一个影响块,对其之前的块更新第一个数与总和,修改点所在的块和最后一个块暴力重构。查询时暴力重构端点所在的块就完了。当然也可以线段树,做法类似。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    using namespace std;
    #define ll long long
    #define N 100010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,q,b[N],block,num,pos[N],L[N],R[N];
    ll S[N],SS[N],sum[N],a[N],first[N],val[N];
    void update(int k)
    {
    	a[L[k]]=first[k];sum[k]=a[L[k]];
    	for (int i=L[k]+1;i<=R[k];i++)
    	a[i]=max(a[i],a[i-1]+b[i-1]),sum[k]+=a[i];
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();block=sqrt(n);num=(n-1)/block+1;
    	for (int i=1;i<=n;i++) a[i]=read();
    	for (int i=1;i<n;i++) b[i]=read();
    	for (int i=1;i<n;i++) S[i]=S[i-1]+b[i];
    	for (int i=1;i<=num;i++)
    	{
    		L[i]=R[i-1]+1;R[i]=min(n,L[i]+block-1);
    		for (int j=L[i];j<=R[i];j++)
    		{
    			if (j==L[i]) SS[j]=0;
    			else SS[j]=SS[j-1]+b[j-1];
    			val[i]+=SS[j];
    			pos[j]=i,sum[i]+=a[j];
    		}
    		first[i]=a[L[i]];
    	}
    	q=read();
    	while (q--)
    	{
    		char c=getchar();
    		while (c!='+'&&c!='s') c=getchar();
    		if (c=='+')
    		{
    			int p=read(),x=read();
    			update(pos[p]);
    			a[p]+=x;if (p==L[pos[p]]) first[pos[p]]+=x;
    			update(pos[p]);
    			int u=num+1;
    			for (int i=pos[p]+1;i<=num;i++)
    			if (first[i]>a[p]+S[L[i]-1]-S[p-1]) {u=i;break;}
    			u--;
    			for (int i=pos[p]+1;i<u;i++)
    			first[i]=a[p]+S[L[i]-1]-S[p-1],
    			sum[i]=1ll*first[i]*(R[i]-L[i]+1)+val[i];
    			if (u!=pos[p])
    			{
    				first[u]=a[p]+S[L[u]-1]-S[p-1];
    				update(u);
    			}
    		}
    		else
    		{
    			int l=read(),r=read();
    			if (pos[l]==pos[r])
    			{
    				update(pos[l]);ll ans=0;
    				for (int i=l;i<=r;i++) ans+=a[i];
    				printf("%I64d
    ",ans);
    			}
    			else
    			{
    				update(pos[l]),update(pos[r]);ll ans=0;
    				for (int i=l;i<=R[pos[l]];i++) ans+=a[i];
    				for (int i=L[pos[r]];i<=r;i++) ans+=a[i];
    				for (int i=pos[l]+1;i<pos[r];i++) ans+=sum[i];
    				printf("%I64d
    ",ans);
    			}
    		}
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      

  • 相关阅读:
    美丽的前端控件
    LeetCode:Rotate List
    VC++ 改动VMware BIOS、uuid_location、ethernet0_address等
    我们错过了那么多机会,怎么办
    怎样在centos安装python-mysql?
    eMMC ext4综述【转】
    闪存中的NorFlash、NandFlash及eMMC三者的区别【转】
    UFS和EMMC的区别--原理学习【转】
    EMMC 介绍【转】
    emmc和ssd的区别【转】
  • 原文地址:https://www.cnblogs.com/Gloid/p/10514921.html
Copyright © 2011-2022 走看看