zoukankan      html  css  js  c++  java
  • [NOIP模拟赛] 2021.11.16

    T1

    对所有长度大于等于3的子区间计算长高成山峰的花费和,一个区间长高成山峰的花费等于每个数字增大的花费和。

    DDG的牛逼单调栈,危黑灵永远游荡在我们周围!

    枚举的是山峰,算贡献只算到这个山峰的。

    极短代码
    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 1000005;
    const int MOD = 1e9+7;
    int n,ans;
    int a[MAXN];
    
    LL Read()
    {
    	LL x = 0,f = 1; char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int s[MAXN],tl;
    
    int main()
    {
    //	freopen("mountain.in","r",stdin);
    //	freopen("mountain.out","w",stdout);
    	n = Read();
    	for(int i = 1;i <= n;++ i) a[i] = Read();
    	for(int i = 1;i <= n;++ i)
    	{
    		while(tl && a[i] >= a[s[tl]])
    		{
    			if(tl > 1) ans = (ans + (n-i+1ll) * (Min(a[i],a[s[tl-1]])-a[s[tl]]) % MOD * (i-s[tl-1]-1) % MOD * s[tl-1] % MOD) % MOD;
    			--tl; 
    		}
    		s[++tl] = i;
    	}
    	Put(ans,'\n');
    	return 0;
    }
    //426406027
    
    

    T2

    赛时切了,是个比较简单的背包。

    赛时代码
    //12252024832524
    #include <bits/stdc++.h>
    #define TT template<typename T>
    using namespace std;
    
    typedef long long LL;
    const int MAXN = 55;
    const int MAXA = 505;
    const int B = 51*500;
    const int C = 500;
    int n,m,ans;
    int a[MAXN][MAXN];
    int dp[2][B<<1|5],r[MAXN][MAXA<<1],c[MAXN][MAXA<<1];
    
    LL Read()
    {
    	LL x = 0,f = 1; char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int main()
    {
    	freopen("matrix.in","r",stdin);
    	freopen("matrix.out","w",stdout);
    	n = Read(); m = Read();
    	for(int i = 0;i < n;++ i)
    		for(int j = 0;j < m;++ j) 
    			a[i][j] = Read();
    	for(int i = 0;i < n;++ i)
    		for(int j = 0;j < m;++ j)
    		{
    			int to = (i-1+n)%n;
    			++r[i][a[i][j]-a[to][j]+C];
    		}
    	for(int i = 0;i < n;++ i)
    		for(int j = 0;j < m;++ j)
    		{
    			int to = (j-1+m)%m;
    			++c[j][a[i][j]-a[i][to]+C];
    		}
    	int L = B,R = B;
    	for(int i = 1;i < n;++ i)
    	{
    		bool now = i&1,to=now^1;
    		memset(dp[now],0,sizeof(dp[now]));
    		int M = 0;
    		for(int j = L;j <= R;++ j) M = Max(M,dp[to][j]);
    		for(int j = L;j <= R;++ j)
    		{
    			for(int kk = 0,k;kk < m;++ kk)
    			{
    				k = a[i][kk] - a[i-1][kk];
    				dp[now][j+k] = Max(dp[now][j+k],dp[to][j]+r[i][k+C]);
    			}
    		}
    		L -= 500; R += 500;
    		for(int j = L;j <= R;++ j) dp[now][j] = Max(dp[now][j],M);
    	}
    	int val = 0;
    	for(int i = L;i <= R;++ i) val = Max(val,dp[(n-1)&1][i]+((C-(i-B) >= 0 && C-(i-B) <= 1000) ? r[0][C-(i-B)] : 0));
    	ans += val;
    	//---
    	L = B,R = B;
    	memset(dp[0],0,sizeof(dp[0]));
    	for(int i = 1;i < m;++ i)
    	{
    		bool now = i&1,to=now^1;
    		memset(dp[now],0,sizeof(dp[now]));
    		int M = 0;
    		for(int j = L;j <= R;++ j) M = Max(M,dp[to][j]);
    		for(int j = L;j <= R;++ j)
    		{
    			for(int kk = 0,k;kk < n;++ kk)
    			{
    				k = a[kk][i] - a[kk][i-1];
    				dp[now][j+k] = Max(dp[now][j+k],dp[to][j]+c[i][k+C]);
    			}
    		}
    		L -= 500; R += 500;
    		for(int j = L;j <= R;++ j) dp[now][j] = Max(dp[now][j],M);
    	}
    	val = 0;
    	for(int i = L;i <= R;++ i) val = Max(val,dp[(m-1)&1][i]+((C-(i-B) >= 0 && C-(i-B) <= 1000) ? c[0][C-(i-B)] : 0));
    	ans += val;
    	Put(ans,'\n');
    	return 0;
    }
    /*
    可以考虑 ri-1 和 ri 满足什么关系可以获得贡献
    地球是个环,所以还是有关的,但是可以dp
    这负数真的恶心至极 
    */
    

    T3

    \/ 不要正方形构造题。

    考虑翻转调整字典序必定变小,所以直接费用流。

    只需从左上到右下定义费用逐渐增大即可,因为费用流优先增广费用小的。

    还可以暴力调整,但是复杂度劣一些。

    T4

    给定一些字符必须转换,可以多次进行,求最大保留字符种类。

    差两点。

    一点是没相当转化成匹配问题,一点是题面出锅打一半就觉得完全不可做。

    其实就是字符去填空,缩点之后变成很多强连通分量。

    一些是需要转化的,一些是可以内部消耗边的(有空的)。

    需要转化的连向可以转到的点(可以也是需要转化的点),最大匹配就是可以保留的最多的字符种类。

    注意一些本来就没有的字符不要算到贡献里面。

  • 相关阅读:
    【React Native】某个页面禁用物理返回键
    【React Native】DeviceEventEmitter监听通知及带参数传值
    转载【React Native代码】手写验证码倒计时组件
    【React Native】 中设置 APP 名称、应用图标、为安卓添加启动图
    【React Native错误集】* What went wrong: Execution failed for task ':app:installDebug'.
    【React Native错误集】Import fails with "Failed to execute 'ImportScripts' on 'WorkerGlobalScope'"
    【React Native错误集】Android error “Could not get BatchedBridge, make sure your bundle is packaged properly” on start of app
    「React Native笔记」在React的 setState 中操作数组和对象的多种方法(合集)
    【React Native】Error: Attribute application@allowBackup value=(false) from AndroidManifest.xml
    坚果云如何使用二次验证码/谷歌身份验证器/两步验证/虚拟MFA?
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15561989.html
Copyright © 2011-2022 走看看