首页 > 其他分享 >题解:【AGC054D】 (ox)

题解:【AGC054D】 (ox)

时间:2023-06-04 15:22:48浏览次数:57  
标签:int 题解 void AGC054D ox inline Mod define

题目链接

Larry76 牛牛 /qq

首先考虑没有 ox 怎么做,就是将括号序列调成合法。\(|S|\) 不大直接模拟一遍,记录 \(now\) 表示一个前缀权值,当遇到一个 ( 时 \(+1\),遇到一个 ) 时 \(-1\),当 \(now < 0\) 的时候说明序列不合法即 ) 多了,暴力向后找到第一个 ( 交换到当前的 ) 前面。这样我们迫不得已时才移动,能够证明得出来的最终括号序列是惟一的。

考虑加入 ox 会造成什么影响。我们先忽略移动 ox 所带来的的影响,假设没有中间间隔的 ox,提出所有的左右括号然后按照上面的方式得到一个合法的括号序列,记这个步数为 rop。注意到我们这样移动即使中间隔着 ox,也不会造成初始 ox 顺序的改变。接下来加入 ox,把先前忽略掉的步数补回来。设 \(f_{i,j}\) 表示当前填入了 \(i\) 个括号和 \(j\) 个 ox,可以发现这个的交换次数贡献为括号和 ox 在原序列上位置的逆序对个数,直接枚举当前填入什么东西。需要特别注意的是记最终括号序列的前缀权值和为 pre,o 可以随意填,但是 x 不能放在两个合法的括号序列之间,即 \(pre_i = 0\) 的位置。

于是代码流程变得十分清晰了:先将左右括号和 ox 分别提出来,记录下它们的初始位置和总个数,设有 \(n\) 个左右括号和 \(m\) 个 ox;然后求纯括号序列的交换次数,并预处理出 pre 数组;最后进行 DP,补偿回算上 ox 的交换次数。最后的答案即为 \(f_{n,m} + rop\)。时间复杂度是 \(\mathcal O(|S|^2)\) 的。

#include<bits/stdc++.h>
#define ld long double
#define ui unsigned int
#define ull unsigned long long
#define int long long
#define eb emplace_back
#define pb pop_back
#define ins insert
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define power(x) ((x)*(x))
#define gcd(x,y) (__gcd(x,y))
#define lcm(x,y) (x*y/gcd(x,y))
#define lg(x,y)  (__lg(x,y))
using namespace std;

namespace FastIO
{
	template<typename T=int> inline T read()
	{
	    T s=0,w=1; char c=getchar();
	    while(!isdigit(c)) {if(c=='-') w=-1; c=getchar();}
	    while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
	    return s*w;
	}
	template<typename T> inline void read(T &s)
	{
		s=0; int w=1; char c=getchar();
		while(!isdigit(c)) {if(c=='-') w=-1; c=getchar();}
	    while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
	    s=s*w;
	}
	template<typename T,typename... Args> inline void read(T &x,Args &...args)
	{
		read(x),read(args...);
	}
	template<typename T> inline void write(T x,char ch)
	{
	    if(x<0) x=-x,putchar('-');
	    static char stk[25]; int top=0;
	    do {stk[top++]=x%10+'0',x/=10;} while(x);
	    while(top) putchar(stk[--top]);
	    putchar(ch);
	    return;
	}
}
using namespace FastIO;

namespace MTool
{
    static const int Mod=998244353;
    template<typename T> inline void Swp(T &a,T &b) {T t=a;a=b;b=t;}
    template<typename T> inline void cmax(T &a,T b) {a=a>b?a:b;}
    template<typename T> inline void cmin(T &a,T b) {a=a<b?a:b;}
    template<typename T> inline void Madd(T &a,T b) {a=a+b>Mod?a+b-Mod:a+b;}
    template<typename T> inline void Mdel(T &a,T b) {a=a-b<0?a-b+Mod:a-b;}
    template<typename T> inline void Mmul(T &a,T b) {a=a*b%Mod;}
    template<typename T> inline void Mmod(T &a)     {a=(a%Mod+Mod)%Mod;}
    template<typename T> inline T    Cadd(T a,T b)  {return a+b>=Mod?a+b-Mod:a+b;}
    template<typename T> inline T    Cdel(T a,T b)  {return a-b<0?a-b+Mod:a-b;}
    template<typename T> inline T    Cmul(T a,T b)  {return a*b%Mod;}
    template<typename T> inline T    Cmod(T a)      {return (a%Mod+Mod)%Mod;}
    inline int qpow(int a,int b) {int res=1; while(b) {if(b&1) Mmul(res,a); Mmul(a,a); b>>=1;} return res;}
    inline int qmul(int a,int b) {int res=0; while(b) {if(b&1) Madd(res,a); Madd(a,a); b>>=1;} return res;}
    inline int Qpow(int a,int b) {int res=1; while(b) {if(b&1) res=qmul(res,a); a=qmul(a,a); b>>=1;} return res;} 
}
using namespace MTool;

inline void file()
{
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
    return;
}

bool Mbe;

namespace LgxTpre
{
    static const int MAX=8010;
    static const int inf=2147483647;
    static const int INF=4557430888798830399;
    static const int mod=1e9+7;
    static const int bas=131;
	
	char s[MAX];
	int n,a[MAX],num,rop,pre[MAX];
	int bck[MAX],cnt,box[MAX],con;
	int f[MAX][MAX],sub1[MAX],sub2[MAX];
	
    inline void mian()
    {
    	scanf("%s",s+1); n=strlen(s+1);
    	for(int i=1;i<=n;++i) 
	    	if(s[i]=='('||s[i]==')') bck[++cnt]=i,a[cnt]=(s[i]=='(')?1:-1;
	    	else box[++con]=i;
	    for(int now=1;now<=cnt;++now)
	    {
	    	if(a[now]&&!num) 
	    	{
	    		int to=now;
	    		while(a[to]!=1) ++to;
	    		rop+=to-now;
	    		while(to>now) Swp(bck[to],bck[to-1]),Swp(a[to],a[to-1]),--to;
			}
			num+=a[now],pre[now]=num;
		}
		memset(f,0x3f,sizeof f),f[0][0]=0;
		for(int i=0;i<=cnt;++i) for(int j=0;j<=con;++j)
		{
			if(i!=cnt&&j) sub1[i]+=box[j]>bck[i+1];
			if(i!=cnt)    cmin(f[i+1][j],f[i][j]+sub1[i]);
			if(j!=con&&i) sub2[j]+=bck[i]>box[j+1];
			if(j!=con&&(pre[i]>0||s[box[j+1]]=='o')) cmin(f[i][j+1],f[i][j]+sub2[j]);
		}
		write(f[cnt][con]+rop,'\n');
    	return;
    }
}

bool Med;

signed main()
{
//  file();
    fprintf(stderr,"%.3lf MB\n",abs(&Med-&Mbe)/1048576.0);
    int Tbe=clock();
    LgxTpre::mian();
    int Ted=clock();
    cerr<<1e3*(Ted-Tbe)/CLOCKS_PER_SEC<<" ms\n";
    return (0-0);
}

标签:int,题解,void,AGC054D,ox,inline,Mod,define
From: https://www.cnblogs.com/LittleTwoawa/p/17455722.html

相关文章

  • Codeforces Round 876 (Div. 2)题解
    CodeforcesRound876(Div.2)A.TheGoodArray标签greedymath题意对于任意\(i\in\{1,2,\dots,n\}\),要求数列\(a\)满足前\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\),后\(i\)个元素中至少有\(\lceil\frac{i}{k}\rceil\)个元素为\(1\)。思......
  • “AIR SDK 0.0: AIR SDK location “...\devsdks\AIRSDK\Win” does not exist.”
    导入AS3项目时提示“AIRSDK0.0:AIRSDKlocation“D:\ProgramFiles\Adob5eFlashBuilder4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\devsdks\AIRSDK\Win”doesnotexist.”是AS3项目找不见AIRSDK.打开项目配置ActionScriptBuildPath,路径出错......
  • CF1329E Dreamoon Loves AA 题解
    令\(p_0=0,m\leftarrowm+1,p_{m}=n,a_i=p_i-p_{i-1}\),设在\((p_{i-1},p_i)\)中有\(d_i-1\)个B变成了A,满足\(\sum_{i=1}^m(d_i-1)=k\),让\(k\leftarrowk+m\),这样\(d\)需要满足的限制就变成了\(\sum_{i=1}^md_i=k\)。这也可以看作把\(a_i\)分成\(d_i\)个正整数之......
  • ABC302Ex Ball Collector 题解
    注意到当有那些\((a_i,b_i)\)是确定的时,答案就是将\((a_i,b_i)\)连边后每个连通块的\(\min(|V|,|E|)\)之和。那么这个东西用可撤销并查集维护即可。#include<algorithm>#include<cstdio>usingnamespacestd;constintN=2e5;structEdge{intto,nxt;}e[......
  • 2023青岛市程序设计竞赛小学组题解
    1.付钱题目链接:https://www.luogu.com.cn/problem/U303904代码:#include<bits/stdc++.h>#definelllonglongusingnamespacestd;intmain(){ lln;cin>>n; cout<<n/100<<''<<(n%100)/50<<''<<(n%50)/20......
  • 第十届蓝桥杯c++b组国赛题解(还在持续更新中...)
    试题A:平方序列解题思路:直接枚举一遍x的取值,然后按照题目给定的式子算出y,每次取x+y的最小值即可答案为7020代码实现:#include<iostream>#include<algorithm>#include<cmath>usingnamespacestd;#defineintlonglongconstintN=1e4+5;signedmain(){ //记录答案......
  • ABC215E 题解
    前言题目传送门!更好的阅读体验?萌萌DP题。思路题目就是在说从\(a\)里面按顺序掏出来一些字母,使得相同的字母都是相邻的(比如AABBBBCD可行,AAABBCAA不行)。看起来很不可做,突破口在于\(\text{A}\sim\text{J}\)一共只有\(10\)个字母,考虑状压。设\(dp_{i,s}\)表示......
  • 【VS Code 与 Qt6】QCheckBox的图标为什么不会切换?
    本篇专门扯一下有关QCheckBox组件的一个问题。老周不水字数,直接上程序,你看了就明白。#include<QApplication>#include<QWidget>#include<QPushButton>#include<QCheckBox>#include<QVBoxLayout>#include<QIcon>intmain(intargc,char**argv){QAp......
  • 道路翻修题解
    \(\mathcal{Description}\)给定一张无向图,为每条边定向,定义每个点的价值为出度与入度之差的绝对值,求最大价值和。对于\(40\%\)的数据,\(1\leqn,m\leq20\)。对于\(70\%\)的数据,\(1\leqn\leq17\)。对于\(90\%\)的数据,\(1\leqn\leq22\)。对于所有数据,\(1\leqn\leq25\)......
  • CF1808E3 题解
    题意传送门求有多少包含\(n\)位数码的\(k\)进制数,满足存在一位数等于其他\(n-1\)位数的总和模\(k\)。\(1\len\le10^{18},1\lek\le2000\)。题解简单的组合数学都不会了……蔬菜越来越多,我该怎么办?条件等价于存在某一位\(x\),满足\(2x\equivs\pmodk\)。容易想到......