Codeforces Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
手玩三四项发现序列就是 $a,b,a\ xor\ b,a,b,...$,直接输出即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
int T,a,b,n;
// a b ab a b
int main()
{
T=read();
while(T--)
{
a=read(),b=read(),n=read();
if(n%==) printf("%d\n",a);
if(n%==) printf("%d\n",b);
if(n%==) printf("%d\n",a^b);
}
return ;
}
$n$ 不大,直接枚举所有左端点,移动右端点并动态维护,数值比较大用 $map$ 即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=;
int n,a[N],tot,ans=N;
map <int,int> sum,cnt,vis;
int main()
{
n=read();
for(int i=;i<=n;i++)
a[i]=read(),sum[a[i]]++;
for(int i=;i<=n;i++)
if(sum[a[i]]>&&!vis[a[i]]) tot++,vis[a[i]]=;
if(!tot) { printf("0\n"); return ; }
for(int i=;i<=n;i++)
{
cnt.clear(); int now=;
for(int j=i;j<=n;j++)
{
cnt[a[j]]++; if(cnt[a[j]]==sum[a[j]]-) now++;
if(now==tot) { ans=min(ans,j-i+); break; }
}
}
printf("%d\n",ans);
return ;
}
又是构造题...
猜一下有规律,发现这样的矩阵横竖异或和都是 $0$:
......
发现 $n$ 一定是 $4$ 的倍数,所以把大矩形分成一些 $4*4$ 的矩形,然后把按上面的规律把矩阵一个个填入即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=;
int n,a[N][N],tot;
int main()
{
n=read();
for(int i=;i<=n;i+=)
for(int j=;j<=n;j+=)
for(int k=;k<;k++)
for(int l=;l<;l++)
a[i+k][j+l]=tot++;
for(int i=;i<=n;i++)
{
for(int j=;j<=n;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return ;
}
正难则反,考虑从后往前确定所有数,对于当前最后面的数,之前所有还没填的小于它的数都会产生贡献,发现当前位置的数越大,前面的贡献也越大
所以根据单调性直接二分最后一个位置的数,维护当前小于某个数的和用树状数组即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline ll read()
{
ll x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e5+;
int n,b[N];
bool vis[N];
ll a[N],t[N];
inline void add(int x,int v) { while(x<=n) t[x]+=v,x+=x&-x; }
inline ll ask(int x) { ll res=; while(x) res+=t[x],x-=x&-x; return res; }
int main()
{
n=read();
for(int i=;i<=n;i++) a[i]=read(),add(i,i);
for(int i=n;i>=;i--)
{
int L=,R=n,mid,res;
while(L<=R)
{
mid=L+R>>;
if(ask(mid-)<=a[i])
{
L=mid+;
if(!vis[mid]) res=mid;
}
else R=mid-;
}
b[i]=res; vis[res]=; add(res,-res);
}
for(int i=;i<=n;i++) printf("%d ",b[i]);
printf("\n");
return ;
}
看一眼直接单调队列走起,然后被区间细节搞死,其实直接 $ST$ 表就可以了..
发现每一行可以分开处理,求出每一行每个位置的贡献加起来就行了
发现如果一行的数不多,那么中间一段位置的贡献都是最大的数,所以只要求出左右两边位置的最大值
发现左右两边的情况都差不多,先考虑左边
对于位置 $i$,在它之前的位置为 $j$ 的数要能够移动到 $i$ 的条件是 $i-j<=m-R$,其中 $m$ 是每一行最大长度,$R$ 是此行的数的数量
然后就可以单调队列维护,右边也同理,注意边界一段也可以没有数,即为 $0$,要记得处理
中间的话,维护一下差分标记即可,一些数组用完一定要记得还原!
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e6+,INF=1e9+;
int n,m;
vector <int> V[N];
ll sum[N],tag[N]; int now[N];
int Q[N],l,r;
int main()
{
n=read(),m=read(); int a;
for(int i=;i<=n;i++)
{
a=read();
for(int j=;j<=a;j++) V[i].push_back(read());
}
memset(now,~0x3f,sizeof(now));//初始为-INF
for(int i=;i<=n;i++)
{
int R=V[i].size(),mx=; l=,r=;
for(int j=;j<=min(m-R,R);j++) now[j]=;
for(int j=m;j>max(m-R,R);j--) now[j]=;//边界可以没有数
for(int j=;j<=R;j++)
{
while(l<=r && j-Q[l]>m-R) l++;
while(l<=r && V[i][j-]>=V[i][Q[r]-]) r--;//记得vector下标从0开始
Q[++r]=j; now[j]=max(now[j],V[i][Q[l]-]); mx=max(mx,V[i][j-]);
}
if(R*<m) tag[R+]+=mx,tag[m-R+]-=mx;//打差分标记
l=,r=;
for(int j=R;j;j--)
{
int p=m-R+j;//当前位置
while(l<=r && Q[l]-j>m-R) l++;
while(l<=r && V[i][j-]>=V[i][Q[r]-]) r--;
Q[++r]=j; now[p]=max(now[p],V[i][Q[l]-]);
}
for(int j=;j<=R;j++) sum[j]+=now[j];//累计贡献
for(int j=max(R+,m-R+);j<=m;j++) sum[j]+=now[j];
for(int j=;j<=R;j++) now[j]=now[m-R+j]=-INF;//记得还原
}
ll S=;
for(int i=;i<=m;i++) S+=tag[i],sum[i]+=S;//处理差分标记
for(int i=;i<=m;i++) printf("%lld ",sum[i]);
printf("\n");
return ;
}
Codeforces Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)的更多相关文章
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-D. Restore Permutation-构造+树状数组 [Pro ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-C. Magic Grid-构造 [Problem Descripti ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-E. Let Them Slide-思维+数据结构
Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)-E. Let Them Slide-思维+数据结构 [Problem ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) F. Bits And Pieces sosdp
F. Bits And Pieces 题面 You are given an array
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) G. Polygons 数论
G. Polygons Description You are given two integers
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2) (1208F,1208G,1208H)
1208 F 大意: 给定序列$a$, 求$\text{$a_i$|$a_j$&$a_k$}(i<j<k)$的最大值 枚举$i$, 从高位到低位贪心, 那么问题就转化为给定$x$ ...
- RMQ+差分处理(Let Them Slide)Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
题意:https://codeforc.es/contest/1208/problem/E 现有n行w列的墙,每行有一排连续方块,一排方块可以左右连续滑动,且每个方块都有一个价值,第i 列的价值定义为 ...
- 线段树维护最后一个0的位置(Restore Permutation)Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)
题意:https://codeforc.es/contest/1208/problem/D 给你长度为n的序列,s[i]的值为p[1]到p[i-1]中比p[i]小的数的和,让你求出p序列. 思路: 首 ...
- Manthan, Codefest 19 (open for everyone, rated, Div. 1 + Div. 2)E(多重集维护)
#define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;long long ans[1000007]; ...
随机推荐
- 049:ORM常用Field详解(1)
常用字段: 在 Django 中,定义了一些 Field 来与数据库表中的字段类型来进行映射.以下将介绍那些常用的字段类型. AutoField: 映射到数据库中是 int 类型,可以有自动增长的特性 ...
- echart-如何将x轴和y轴的原点进行重合???
设计稿突然让x轴 和y轴重合,我们可以设置图中的这个属性. 不知道还有没有别的设置属性,欢迎评论指出谢谢
- mysql Alias操作符 语法
mysql Alias操作符 语法 作用:为列名称和表名称指定别名 大理石构件 语法:SELECT column_name(s) FROM table_name AS alias_name mysql ...
- Java——super
在Java类中使用super来引用基类的成分. [代码]
- javascript之alter的坑
1.注意在使用alert返回两数之和时,会出现0.1+0.2并不等于0.3的bug 解决方法: var f=0.1; var g=0.2; alert((parseFloat(f)*100+parse ...
- Java数据结构与算法(3):队列
队列也是一种表,不同的是队列在一端进行插入而在另一端进行删除. 队列模型 队列的基本操作包括入队.出队操作.在表的末端插入元素,在表的开头删除元素,即先进先出(FIFO). 队列的数组实现 对于每一个 ...
- Mybatis传多个参数(三种解决方案) mapper.xml的sql语句修改!
第一种 Public User selectUser(String name,String area); 对应的Mapper.xml <select id="selectUser&qu ...
- ERROR 1366 (HY000): Incorrect string value:MySQL数据库、表的字符集为GBK
mysql> update userinfo set MEDIASOURCE = 'CS02-北京' where IMPORTNO = 'IMP201640613101206';ERROR 13 ...
- linux管理权限
1.linux命令查询 root id 2.切换用户 su - xiaobai 一定要加" - "这个会将你的所有环境变量都带过来 3.root用户切换普通用户不需要输入密码反 ...
- 使用Chrome逆向分析JS实战---分析google网站翻译器原文存放位置
剧透:就是使用了一下Chrome DevTools的Memory功能,通过已知的JS变量的值查找JS内存中变量的引用 一:不分析一下现有的网页翻译方法么? 总所周知,(As is well known ...