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]; ...
随机推荐
- [CF1004E] Sonya and Ice-cream
问题描述 Sonya likes ice cream very much. She eats it even during programming competitions. That is why ...
- mybatis动态update语句
- JDK7的新特性
本篇博客的内容 一.二进制字面量 二.数字字面量可以出现下划线 三.switch 语句可以用字符串 四.泛型简化 五.异常的多个catch合并 六.try-with-resources 语句 一.二进 ...
- JDK,JRE与JVM浅析
JAVA的两个特性: 1, 开源-指的是源代码免费 2,跨平台(可移植性好) 跨平台:是指跨操作系统 JVM(java virtual machine,java虚拟机) JVM就像是两国谈判时的使者充 ...
- POJ 3061 Subsequence ( 二分 || 尺取法 )
题意 : 找出给定序列长度最小的子序列,子序列的和要求满足大于或者等于 S,如果存在则输出最小长度.否则输出 0(序列的元素都是大于 0 小于10000) 分析 : 有关子序列和的问题,都可以考虑采用 ...
- 创建maven web项目时,没有web.xml文件
1.问题:创建maven项目时,选择的是创建web-app项目,但是结果配置之后,却没有web.xml文件. 2.解决办法: ------------------------------------- ...
- css内容过长显示省略号的几种解决方法
单行文本(方法一): 语法: text-overflow : clip | ellipsis 参数: clip : 不显示省略标记(...),而是简单的裁切 (clip这个参数是不常用的!) elli ...
- Android单行跑马灯效果实现
参考网址:https://www.jianshu.com/p/e6c1b825d322 起初,使用了如下XML布局: <TextView android:id="@+id/tv_per ...
- 微信小程序image组件
image组件:是小程序专门针对图片的组件,功能强大 image组件的属性: src:类型 字符串 图片资源的路径 mode:类型 字符串 图片裁剪缩放模式 lazy-load:类型 布尔 图片的懒加 ...
- Visual Studio使用技巧 +谷歌浏览器使用技巧总结
一.总结下visual studio常用的使用技巧,有助于提高效率: 1.给代码行打标记: ctrl + K :给行打标记:ctrl + K + N:切换标记,即使当前页关闭了,也可以适用此快捷键快 ...