CF Round 1305(Ozen)
A##
很水
B.模拟##
给定一个括号序列,求至少删除多少次使得原序列中不存在「好子序列」并输出删除方案,如果本身就没有「好子序列」则输出 0。
「好子序列」的定义是长度为 2k 且 1∼k都为 ( ,k+1∼2k都是 ) 的子序列。删除操作规定每次只能选择原序列中的一个「好子序列」并删除其中的全部元素。
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
using namespace std;
#define INF 1e10+5
#define MAXN 105
#define MINN -105
typedef long long int LL;
struct node
{
vector<int>num;
void put(int i)
{
num.push_back(i);
}
void out()
{
vector<int>::iterator it=num.begin();
for(;it!=num.end();it++)
cout<<*it<<" ";
cout<<endl;
}
};
int main()
{
string s;
int a[1005],b[1005];
cin>>s;
int l=1,r=1;
int n=s.size();
node Node[1000];
int cse=0;
while(1)
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
a[0]=b[n-1]=0;
int index,curmax=0;
for(int i=0;i<s.size();i++)
{if(i)a[i]=a[i-1];if(s[i]=='(')a[i]++;}
for(int i=s.size()-1;i>=0;i--)
{if(i<n-1)b[i]=b[i+1];if(s[i]==')')b[i]++;
if(curmax<min(a[i],b[i]))
{
curmax=min(a[i],b[i]);
index=i;
}
}
if(!curmax)break;
cse++;
int cur=0;
for(int i=0;i<=index;i++)
{
if(cur==curmax)break;
if(s[i]=='(')
{
cur++;
s[i]='*';
Node[cse].put(i+1);
}
}
cur=0;
for(int i=index;i<=s.size();i++)
{
if(cur==curmax)break;
if(s[i]==')')
{
cur++;
s[i]='*';
Node[cse].put(i+1);
}
}
}
if(!cse)cout<<0<<endl;
else
{
cout<<cse<<endl;
for(int i=1;i<1000;i++)
if(!Node[i].num.empty())
{
cout<<Node[i].num.size()<<endl;
Node[i].out();
}
}
return 0;
}
c.数学,鸽巢原理##
数据范围给的很大,n<=20,000,但是m很小
这就是鸽巢定理的使用啦
显然当n>m的时候,肯定有两个元素%m是同值的,所以必定为0
那么当n<=m暴力一下就可以啦
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define INF 1e10+5
#define MAXN 200015
#define MINN -105
typedef long long int LL;
int main()
{
LL n,m,a[MAXN];
cin.tie();
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
if(n>m)
{
cout<<0<<endl;
return 0;
}
else
{
LL ans=1;
for(int i=2;i<=n;i++)
for(int j=1;j<i;j++)
{
ans=(ans*(LL)abs(a[i]-a[j]))%m;
}
cout<<ans<<endl;
}
return 0;
}