Technocup 2020 Elimination Round 3题解
\(A\)
曲明连sb模拟不会做,拖出去埋了算了
//quming
#include<bits/stdc++.h>
#define R register
#define fi first
#define se second
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
typedef pair<int,int> pi;
const int N=2005;
char s[N];int n,k,top,T;pi st[N];
void find(int pos,int c){
if(s[pos]==c)return;
fp(i,pos+1,n)if(s[i]==c){
st[++top]=pi(pos,i),reverse(s+pos,s+i+1);
return;
}
}
int main(){
for(scanf("%d",&T);T;--T){
scanf("%d%d",&n,&k),top=0,--k;
scanf("%s",s+1);
fp(i,1,k<<1)find(i,(i&1)?'(':')');
R int sz=n-(k<<1);
fp(i,1,sz)find(i+(k<<1),i<=sz?'(':')');
printf("%d\n",top);
fp(i,1,top)printf("%d %d\n",st[i].fi,st[i].se);
}
return 0;
}
\(B\)
离线之后sort一下依次加入每个元素,每次查询\(k\)大值就行了,我抄了个平衡树板子,实际上二分+树状数组就行了
//quming
#include<bits/stdc++.h>
#define R register
#define pb push_back
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
unsigned int aaa=19260817;
inline unsigned int rd(){aaa^=aaa>>15,aaa+=aaa<<12,aaa^=aaa>>3;return aaa;}
const int N=2e5+5;
struct node;typedef node* ptr;
struct node{
ptr lc,rc;int v,sz;unsigned int pr;
inline void init(R int val){v=val,pr=rd(),sz=1;}
inline ptr upd(){return sz=lc->sz+rc->sz+1,this;}
}e[N],*rt=e;int tot;
inline ptr newnode(R int v){return e[++tot].init(v),(e+tot)->lc=(e+tot)->rc=e,e+tot;}
void split(ptr p,int k,ptr &s,ptr &t){
if(p==e)return s=t=e,void();
if(p->v<=k)s=p,split(p->rc,k,p->rc,t);
else t=p,split(p->lc,k,s,p->lc);
p->upd();
}
ptr merge(ptr s,ptr t){
if(s==e)return t;if(t==e)return s;
if(s->pr<t->pr)return s->rc=merge(s->rc,t),s->upd();
return t->lc=merge(s,t->lc),t->upd();
}
void insert(int k){
ptr s,t;
split(rt,k,s,t);
rt=merge(merge(s,newnode(k)),t);
}
void erase(int k){
ptr s,t,p;
split(rt,k,s,t),split(s,k-1,s,p),p=merge(p->lc,p->rc);
rt=merge(merge(s,p),t);
}
int rk(int k){
ptr s,t;int now;
split(rt,k-1,s,t);now=s->sz+1;
return rt=merge(s,t),now;
}
int Kth(ptr p,int k){
if(p->lc->sz==k-1)return p->v;
if(p->lc->sz>=k)return Kth(p->lc,k);
return Kth(p->rc,k-p->lc->sz-1);
}
int Pre(int k){
ptr s,t;int now;
split(rt,k-1,s,t),now=Kth(s,s->sz);
return rt=merge(s,t),now;
}
int nxt(int k){
ptr s,t;int now;
split(rt,k,s,t),now=Kth(t,1);
return rt=merge(s,t),now;
}
int a[N],id[N],ak[N],ad[N],ans[N],n,m;
vector<int>qr[N];
int main(){
scanf("%d",&n);
fp(i,1,n)scanf("%d",&a[i]),id[i]=i;
sort(id+1,id+1+n,[](const int &x,const int &y){return a[x]==a[y]?x<y:a[x]>a[y];});
scanf("%d",&m);
fp(i,1,m)scanf("%d%d",&ak[i],&ad[i]),qr[ak[i]].pb(i);
fp(i,1,n){
insert(id[i]);
for(auto v:qr[i])ans[v]=Kth(rt,ad[v]);
}
fp(i,1,m)printf("%d\n",a[ans[i]]);
return 0;
}
\(C\)
曲明连sb二分都不会做,可以拖出去埋了
//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=1e6+5;
char s[N];
vector<int>sm[N],a[N],d[N],g[N];
int n,m,cnt,h,t,l,r,mid,ans;
inline void init(){
fp(i,0,n+1){
sm[i].resize(m+2),
a[i].resize(m+2),
d[i].resize(m+2),
g[i].resize(m+2);
}
}
inline int calc(R int x,R int y,R int xx,R int yy){
return sm[xx][yy]+sm[x-1][y-1]-sm[x-1][yy]-sm[xx][y-1];
}
inline bool ok(R int i,R int j,R int mid){
return calc(i-mid,j-mid,i+mid,j+mid)==(mid<<1|1)*(mid<<1|1);
}
bool ck(){
fp(i,0,n+1)fp(j,0,m+1)g[i][j]=0;
fp(i,mid+1,n-mid)fp(j,mid+1,m-mid)
if(ok(i,j,mid)){
++g[i-mid][j-mid],++g[i+mid+1][j+mid+1];
--g[i-mid][j+mid+1],--g[i+mid+1][j-mid];
}
R int fl=1;
fp(i,1,n)fp(j,1,m){
g[i][j]+=g[i-1][j]+g[i][j-1]-g[i-1][j-1];
if((g[i][j]>0)!=a[i][j])fl=0;
}
return fl;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d",&n,&m);init();
fp(i,1,n){
scanf("%s",s+1);
fp(j,1,m){
a[i][j]=(s[j]=='X');
sm[i][j]=sm[i-1][j]+sm[i][j-1]-sm[i-1][j-1]+a[i][j];
}
}
l=0,r=min(n+1,m+1)>>1,ans=0;
while(l<=r){
mid=(l+r)>>1;
ck()?(ans=mid,l=mid+1):r=mid-1;
}
printf("%d\n",ans);
fp(i,1,n)fp(j,1,m)d[i][j]=0;
fp(i,ans+1,n-ans)fp(j,ans+1,m-ans)d[i][j]=ok(i,j,ans);
fp(i,1,n){
fp(j,1,m)putchar(d[i][j]?'X':'.');
putchar('\n');
}
return 0;
}
\(D\)
记一个\(c\),考虑每个\(i\),如果\(a_i=h_i\)令\(--c\),如果\(a_i=h_{i+1}\)令\(++c\),相当于求最终\(c>0\)的方案,那么根据\(h_i\)和\(h_{i+1}\)是否相等判断一下\(a_i\)对\(c\)的贡献写出生成函数,手动多项式快速幂就行了
//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=998244353;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int inc(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
const int N=(1<<19)+5;
int rt[2][N],r[21][N],inv[21],lg[N],lim,d;
void init(){
fp(d,1,19){
fp(i,1,(1<<d)-1)r[d][i]=(r[d][i>>1]>>1)|((i&1)<<(d-1));
inv[d]=ksm(1<<d,P-2),lg[1<<d]=d;
}
for(R int t=(P-1)>>1,i=1,x,y;i<524288;t>>=1,i<<=1){
x=ksm(3,t),y=ksm(332748118,t),rt[0][i]=rt[1][i]=1;
fp(k,1,i-1){
rt[0][i+k]=mul(rt[0][i+k-1],x);
rt[1][i+k]=mul(rt[1][i+k-1],y);
}
}
}
void NTT(int *A,int ty){
int t;
fp(i,0,lim-1)if(i<r[d][i])swap(A[i],A[r[d][i]]);
for(R int mid=1;mid<lim;mid<<=1)
for(R int j=0;j<lim;j+=(mid<<1))
fp(k,0,mid-1){
A[j+k+mid]=inc(A[j+k],P-(t=mul(A[j+k+mid],rt[ty][mid+k])));
upd(A[j+k],t);
}
if(!ty){
t=inv[d];
fp(i,0,lim-1)A[i]=mul(A[i],t);
}
}
int A[N],a[N];
int n,k,res,coef,cnt;
int main(){
// freopen("testdata.in","r",stdin);
init();
scanf("%d%d",&n,&k);
fp(i,1,n)scanf("%d",&a[i]);
a[n+1]=a[1];
fp(i,1,n)++(a[i]==a[i+1]?coef:cnt);
if(coef==n)return puts("0"),0;
coef=ksm(k%P,coef);
A[0]=A[2]=1,A[1]=(k-2)%P;
lim=1,d=0;while(lim<=(cnt<<1))lim<<=1,++d;
NTT(A,1);
fp(i,0,lim-1)A[i]=ksm(A[i],cnt);
NTT(A,0);
fp(i,cnt+1,(cnt<<1))upd(res,A[i]);
printf("%d\n",mul(res,coef));
return 0;
}
\(E\)
首先默认\(a_i\leq a_{i+1}\),并且默认\(a_i\leq n-1\)
这样的话我们就可以有一种放法,对于一个\(n\times n\)的网格,强制副对角线上所有格子不能放元素,然后每一列都从这一列的副对角线格子上方开始放起,这样由于\(a_i\leq a_{i+1}\),所以相邻两列的放了元素的格子的顶端一定不同
大概长这样,红色表示不能放,黑色表示放了的格子,\(a_2=a_3=a_4=2\),但它们的顶端各不相同

这样的话我们可以证明任意两行一定不同
如果有的元素满足\(a_i=n\),然后我们直接把它的第\(n\)个元素扔到第\(n+1\)行,有可能出现的一个问题就是第\(n\)行和第\(n+1\)行相等。一种解决办法就是我们找到第\(n+1\)行的黑格子的左边界,记为\(i\),由于\(i\)是左边界,那么第\(n\)行里第\(i-1\)个格子一定是白的,我们把第\(n+1\)行第\(i\)个格子和第\(i\)列副对角线上那个格子交换,容易证明这样之后依然是合法的


//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int N=1005;
int mp[N][N],a[N],id[N],n;
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d",&n);
fp(i,1,n)scanf("%d",&a[i]),id[i]=i;
sort(id+1,id+1+n,[](const int &x,const int &y){return a[x]<a[y];});
fd(i,n,1)for(R int j=n-i,k=1;k<=min(n-1,a[id[i]]);++k,--j){
if(!j)j=n;
mp[j][id[i]]=1;
}
fp(i,1,n)if(a[i]==n)mp[n+1][i]=1;
R bool fl=1;
fp(i,1,n)if(mp[n][i]!=mp[n+1][i]){fl=0;break;}
if(fl){
// puts("QAQ");
fd(i,n,1)if(a[id[i]]==n&&a[id[i-1]]!=n){
mp[n+1][id[i]]=0,mp[n-i+1][id[i]]=1;
break;
}
}
printf("%d\n",n+1);
fp(i,1,n+1){
fp(j,1,n)putchar(mp[i][j]+'0');
putchar('\n');
}
return 0;
}
\(F\)
我们把所有的线段都拆成形如\([x,x+2^k-1]\)的样子,其中\(x\)的二进制的\(0\)到\(k-1\)位全都为\(0\),对于一条原来的线段,拆掉它之后产生的所有线段其实就是\(l\)和\(r\)的trie树上的路径的所有儿子,所以我们可以证明拆完之后总线段数是\(O(n\times 60)\)的
对于两条形如\([x,x+2^k-1]\)和\([y,y+2^g-1]\)的线段,假设\(k<g\),并设\(p=x\oplus y\)的前\(59-g\)位,我们发现这两条线段可以异或出\([p,p+2^g-1]\)之间的所有数字,而且\(p\)是一个固定的前缀。所以我们可以枚举所有合法的线段,而最终的贡献就相当于trie树的一个子树全部合法,打上标记就行了,最后在trie树上dfs一遍就行了,总复杂度\(O(n^260^3)\),卡一卡就能过
//quming
#include<bits/stdc++.h>
#define R register
#define fi first
#define se second
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
const int P=998244353;
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int inc(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))(y&1)?res=mul(res,x):0;
return res;
}
typedef long long ll;
typedef pair<ll,int> pi;
typedef pair<ll,ll> ppi;
const int N=200005;
int n,na,nb,top;pi sa[N],sb[N];ppi st[N];
void get(){
scanf("%d",&n);
fp(i,1,n)scanf("%lld%lld",&st[i].fi,&st[i].se);
sort(st+1,st+1+n,[](const ppi &a,const ppi &b){return a.fi<b.fi;});
top=1;
fp(i,2,n)if(st[i].fi<=st[top].se+1)cmax(st[top].se,st[i].se);
else st[++top]=st[i];
}
void build(pi *s,int &n,ll l,ll r){
for(R ll i=l,p=0;i<=r;i+=(1ll<<p)){
while((i>>p&1^1)&&(i+(1ll<<(p+1))-1)<=r)++p;
while(p&&(i+(1ll<<p)-1)>r)--p;
s[++n]=pi(i,p);
}
}
const int M=1e7+5;
int ch[M][2],vis[M],bin[233],nd,res;
void ins(R ll x,int k){
R int p=0,c;
fd(i,59,k){
c=(x>>i&1);
if(!ch[p][c])ch[p][c]=++nd;
if(vis[p=ch[p][c]])return;
}
vis[p]=1;
}
void dfs(int p,int pos,int coef){
if(vis[p]){
upd(res,mul(coef,bin[pos+1]));
upd(res,mul(bin[pos+1]-1,bin[pos]));
return;
}
if(ch[p][0])dfs(ch[p][0],pos-1,coef);
if(ch[p][1])dfs(ch[p][1],pos-1,inc(coef,bin[pos]));
}
int main(){
// freopen("testdata.in","r",stdin);
get();
fp(i,1,top)build(sa,na,st[i].fi,st[i].se);
get();
fp(i,1,top)build(sb,nb,st[i].fi,st[i].se);
bin[0]=1;fp(i,1,60)bin[i]=mul(bin[i-1],2);
sort(sa+1,sa+1+na,[](const pi &a,const pi &b){return a.se>b.se;});
sort(sb+1,sb+1+nb,[](const pi &a,const pi &b){return a.se>b.se;});
fp(i,1,na)fp(j,1,nb)ins(sa[i].fi^sb[j].fi,max(sa[i].se,sb[j].se));
dfs(0,59,0);
printf("%lld\n",res);
return 0;
}
Technocup 2020 Elimination Round 3题解的更多相关文章
- Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4) 题解
Happy Birthday, Polycarp! Make Them Odd As Simple as One and Two Let's Play the Words? Two Fairs Bea ...
- Codeforces Round #591 (Div. 2, based on Technocup 2020 Elimination Round 1) 题解
A..B略 C 对当前的值排序,再二分答案,然后对于(i%x==0 && i%y==0)放入大的,再放其他的贪心解决即可. #include<iostream> #incl ...
- Codeforces Round #596 (Div. 2, based on Technocup 2020 Elimination Round 2)
A - Forgetting Things 题意:给 \(a,b\) 两个数字的开头数字(1~9),求使得等式 \(a=b-1\) 成立的一组 \(a,b\) ,无解输出-1. 题解:很显然只有 \( ...
- 20191214 Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)
概述 切了 ABCE,Room83 第一 还行吧 A - Happy Birthday, Polycarp! 题解 显然这样的数不会很多. 于是可以通过构造法,直接求出 \([1,10^9]\) 内所 ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) F2. Wrong Answer on test 233 (Hard Version) dp 数学
F2. Wrong Answer on test 233 (Hard Version) Your program fails again. This time it gets "Wrong ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) E. Arson In Berland Forest 二分 前缀和
E. Arson In Berland Forest The Berland Forest can be represented as an infinite cell plane. Every ce ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) D2. Optimal Subsequences (Hard Version) 数据结构 贪心
D2. Optimal Subsequences (Hard Version) This is the harder version of the problem. In this version, ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) C. Messy 构造
C. Messy You are fed up with your messy room, so you decided to clean it up. Your room is a bracket ...
- Codeforces Round #602 (Div. 2, based on Technocup 2020 Elimination Round 3) B. Box 贪心
B. Box Permutation p is a sequence of integers p=[p1,p2,-,pn], consisting of n distinct (unique) pos ...
随机推荐
- ImportBeanDefinitionRegistrar接口实现bean动态注入
借助ImportBeanDefinitionRegistrar接口实现bean的动态注入https://www.jianshu.com/p/2b993ced6a4c ImportBeanDefinit ...
- 八.软件自动化和web测试
1.软件自动化测试 1.1 自动化测试的概念 自动化测试:就是通过测试工具或其他手段,按照测试工程师的预定计划对软件产品进行自动化的测试 软件测试自动化涉及到测试流程.测试体系.自动化编译以 ...
- 任意图像尺寸变成目标尺寸(包含相应的boxes的变换)
def image_preporcess(image, target_size, gt_boxes=None): image = cv2.cvtColor(image, cv2.COLOR_BGR2R ...
- 含有动态未知字段的 JSON 反序列化
一般来说,正常的 json 长这个模样: { 'Name': 'Bad Boys', 'ReleaseDate': '1995-4-7T00:00:00', 'Genres': [ 'Action', ...
- kubernetes V1.16 Ingress-nginx部署
Ingress 在Kubernetes中,服务和Pod的IP地址仅可以在集群网络内部使用,对于集群外的应用是不可见的.为了使外部的应用能够访问集群内的服务,在Kubernetes中可以通过NodePo ...
- js中 json对象与json字符串相互转换的几种方式
以下总结js中 json对象与json字符串相互转换的几种方式: 一.JSON对象转化为JSON字符串 1.使用JSON.stringify()方法进行转换 该方法不支持较老版本的IE浏览器,比如:i ...
- Ubuntu下 安卓 adb 命令报:“insufficient permissions for device: user in plugdev group; ”问题的解决办法
https://blog.csdn.net/freezingxu/article/details/80893025 在接入设备进行联机调试的时候,遇到了这样的问题: insufficient perm ...
- httpget请求测试用Java代码的实现方法
原文:http://www.cnblogs.com/johnson-yuan/p/6637906.html 1.首先要在eclipse中导入HttpClient的jar包. 2.新建类并写入一下代码: ...
- mysql 触发器、流程控制、事务等
视图 触发器 事务 存储过程 内置函数 流程控制 索引 视图 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以 ...
- VUE router-view key 属性解释
router-view 作用, 你可以 router-view 当做是一个容器,它渲染的组件是你使用 vue-router 指定的. <template> <section clas ...