Gym 101889:2017Latin American Regional Programming Contest(寒假自训第14场)
昨天00.35的CF,4点才上床,今天打的昏沉沉的,WA了无数发。 题目还是满漂亮的。 尚有几题待补。
C .Complete Naebbirac's sequence
题意:给定N个数,他们在1到K之间,现在1到K的出现次数的不完全相同的,现在让你进行一次操作,使得他们相同。 操作是加一个数到集合; 或者删去一个数; 或同时一个数,删一个数。
思路:枚举三种情况即可。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int a[maxn],num[maxn],N,M;
bool checkdel()
{
int cnt=,x=;
if((N-)%M==) {
rep(i,,M) if(num[i]==(N-)/M+) x=i;
else if(num[i]==(N-)/M) cnt++;
}
else return false;
if((cnt==M-)&&x) {
printf("-%d\n",x);
return true;
}
return false;
}
bool checkadd()
{
bool F=true; int x=,cnt=;
if((N+)%M!=) return false;
rep(i,,M) if(num[i]==(N+)/M) cnt++;
else if(num[i]==(N+)/M-)x=i;
if((cnt==M-)&&x){
printf("+%d\n",x);
return true;
}
return false;
}
bool checkadc()
{
bool F=true; int cnt=,x=,y=;
if(N%M!=) return false;
rep(i,,M) {
if(num[i]==N/M) cnt++;
else if(num[i]>N/M) x=i;
else if(num[i]<N/M) y=i;
}
if(cnt==M-&num[x]==num[y]+) {
printf("-%d +%d\n",x,y); return true;
}
return false;
}
int main()
{
scanf("%d%d",&M,&N);
rep(i,,N) scanf("%d",&a[i]),num[a[i]]++;
if(checkadd()) return ;
if(checkadc()) return ;
if(checkdel()) return ;
puts("*");
return ;
}
D .Daunting device
题意:N个格子排出一排,开始格子颜色都是1;现在有M个操作: N,M<1e5
或,把区间[L,R]颜色改为c; 或,查询一共有多少格子颜色为c。 最后求颜色最多的数量。
数据是随机的,且强制在线。
思路:ODT裸题。维护相同颜色的区间。注意split的时候先split(R+1),再split(L);因为这个我wa20了;
在这里有写。 大概就是会改变指针啥的,我对iterator不了解,所以不知道,记下来好了。
开始想的分块也能做,但是我感觉还带个log。N*sqrt*log,数据水的话没准可以。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
struct in{
int L,R,v;
in(){}
in(int LL,int RR,int vv):L(LL),R(RR),v(vv){}
friend bool operator<(in a,in b){
if(a.L==b.L) return a.R<b.R;
return a.L<b.L;
}
};
set<in>s;
#define IT set<in>::iterator
int num[],ans;
IT split(int pos)
{
IT it=s.lower_bound(in(pos,-,-));
if(it!=s.end()&&(*it).L==pos) return it;
it--; //if(pos>it->R) return s.end();
int l=(*it).L,r=(*it).R,v=(*it).v;
s.erase(it);
s.insert(in(l,pos-,v));
return s.insert(in(pos,r,v)).first;
}
void Assign(int L,int R,int X)
{
IT it2=split(R+),it1=split(L);
for(IT it=it1;it!=it2;it++) {
num[(*it).v]-=((*it).R-(*it).L+);
}
s.erase(it1,it2);
s.insert(in(L,R,X));
num[X]+=R-L+;
}
int main()
{
int N,L,C,P,X,A,B,S;
scanf("%d%d%d",&L,&C,&N);
s.insert(in(,L-,)); num[]=L;
rep(i,,N){
scanf("%d%d%d%d",&P,&X,&A,&B); A%=L; B%=L;
S=num[P]%L;
int l=(A+1LL*S*S%L)%L,r=(A+1LL*(S+B)*(S+B)%L)%L;
Assign(min(l,r),max(l,r),X);
}
rep(i,,C) ans=max(ans,num[i]);
printf("%d\n",ans);
return ;
}
E .Enigma
题意:给定一个字符串c[]和整数N,,或者是'?',或者是数字, '?'表示你可以替换为数字。 让你求字典序最小的c,满足他是N的倍数, |c|,N<1000;无解输出"*";
思路:显然是DP,dp[i][j]表示前i位%N是否可以为j; 开始时,dp[0][0]=1; 然后做背包,最后倒着来,就可以得到最小字典序了。O(N^2);
注意第一位不能为0;
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int maxn=;
char c[maxn]; int dp[maxn][maxn],N,L,fac[maxn];
int main()
{
scanf("%s%d",c+,&N);
L=strlen(c+);
fac[]=%N; rep(i,,L) fac[i]=fac[i-]*%N;
dp[L+][]=;
rep2(i,L,){
if(c[i]=='?'){
rep(k,,)
rep(j,,N-)
dp[i][(j+k*fac[L-i])%N]|=dp[i+][j];
}
else {
rep(j,,N-)
dp[i][(j+(c[i]-'')*fac[L-i])%N]|=dp[i+][j];
}
}
if(!dp[][]) puts("*");
else{
int now=;
rep(i,,L){
if(c[i]!='?'){
putchar(c[i]);
now=((now-(c[i]-'')*fac[L-i])%N+N)%N;
}
else{
rep(j,,){
if(i==&&j==) continue;
if(dp[i+][((now-j*fac[L-i])%N+N)%N]) {
printf("%d",j);
now=((now-j*fac[L-i])%N+N)%N;
break;
}
}
}
}
}
return ;
}
F .Fundraising
题意:现在有N个慈善家,每个人有ai和bi属性,以及准备捐的款ci。有矛盾的慈善家不能同时出场,两个人有矛盾,当前仅当(ai-aj)*(bi-bj)<0;问怎么安排出场捐款最大。
思路:典型的一维排序,一维用线段树或者树状数组更新DP值。
注意有两个人的a和b完全相同的情况,我们把ci小的那个人删去。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
struct in{
int b,f;ll d;
friend bool operator <(in w,in v){
if(w.b!=v.b) return w.b<v.b;
return w.f>v.f;
}
}s[maxn];
ll Mx[maxn],res[maxn],ans; int b[maxn],tot;
void update(int Now,int L,int R,int pos,ll val)
{
if(L==R){Mx[Now]=max(Mx[Now],val); return ;}
int Mid=(L+R)>>;
if(pos<=Mid) update(Now<<,L,Mid,pos,val);
else update(Now<<|,Mid+,R,pos,val);
Mx[Now]=max(Mx[Now<<|],Mx[Now<<]);
}
ll query(int Now,int L,int R,int l,int r)
{
if(l<=L&&r>=R) return Mx[Now];
int Mid=(L+R)>>; ll res=;
if(l<=Mid) res=max(res,query(Now<<,L,Mid,l,r));
if(r>Mid) res=max(res,query(Now<<|,Mid+,R,l,r));
return res;
}
int main()
{
int N; scanf("%d",&N);
rep(i,,N){
scanf("%d%d%lld",&s[i].b,&s[i].f,&s[i].d);
b[++tot]=s[i].f;
}
sort(b+,b+tot+); tot=unique(b+,b+tot+)-(b+);
rep(i,,N) s[i].f=lower_bound(b+,b+tot+,s[i].f)-b;
sort(s+,s+N+);
rep(i,,N-) {
if(s[i].f==s[i+].f&&s[i].b==s[i+].b) s[i+].d+=s[i].d,s[i].d=;
}
sort(s+,s+N+);
rep(i,,N) {
int j=i;
while(j+<=N&&s[j].b==s[j+].b) j++;
rep(k,i,j) {
if(s[k].f>)res[k]=query(,,tot,,s[k].f-);
res[k]+=s[k].d;
ans=max(ans,res[k]);
}
rep(k,i,j)
update(,,tot,s[k].f,res[k]);
i=j;
}
printf("%lld\n",Mx[]);
return ;
}
H .Hard choice
by .pb 应该是个水题,懒得看了
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a,b,c,x,y,z;
template<class T>
inline void read(T&a){
char c=getchar();
for(a=;(c<''||c>'')&&c!='-';c=getchar());
bool f=;if(c=='-')f=,c=getchar();
for(;c>=''&&c<='';c=getchar())a=a*+c-'';
if(f)a=-a;
}
int main(){
read(a),read(b),read(c),read(x),read(y),read(z);
printf("%d\n",max(,x-a)+max(y-b,)+max(z-c,));
return ;
}
I .Imperial roads
题意:给定N点M边带权连通图,现在Q次询问,每次问在必选某条边的情况下,最小生成树的大小。
思路:先建一个MST,大小为sum, 如果询问边已经在树上,那么答案是sum; 否则,ans=sum-len+maxedge(u->lca->v);
即是用环里最大替换掉。。。老掉牙的基础题了,可以用树剖或者倍增求路径最大边权。
#include<bits/stdc++.h>
#define pii pair<int,int>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
using namespace std;
const int maxn=;
struct in{
int u,v,len;
friend bool operator<(in a,in b){ return a.len<b.len; }
}s[maxn];
int fa[maxn],dep[maxn],f[maxn][],Mx[maxn][];
int Laxt[maxn],Next[maxn<<],To[maxn<<],Len[maxn<<],cnt;
map<pii,int>mp;
void add(int u,int v,int w){
Next[++cnt]=Laxt[u]; Laxt[u]=cnt;To[cnt]=v;Len[cnt]=w;
}
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void dfs(int u,int pre)
{
f[u][]=pre; dep[u]=dep[pre]+;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]!=pre){
dfs(To[i],u);
Mx[To[i]][]=Len[i];
}
}
}
int LCA(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);
rep2(i,,) if(dep[f[u][i]]>=dep[v]) u=f[u][i];
if(u==v) return u;
rep2(i,,) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
return f[u][];
}
int query(int u,int v)
{
int Lca=LCA(u,v),res=;
rep2(i,,) if(dep[f[u][i]]>=dep[Lca]) {
res=max(res,Mx[u][i]);u=f[u][i];
}
rep2(i,,) if(dep[f[v][i]]>=dep[Lca]) {
res=max(res,Mx[v][i]);v=f[v][i];
}
return res;
}
int main()
{
int N,M,Q,u,v,sum=;
scanf("%d%d",&N,&M);
rep(i,,N) fa[i]=i;
rep(i,,M){
scanf("%d%d%d",&s[i].u,&s[i].v,&s[i].len);
if(s[i].u>s[i].v) swap(s[i].u,s[i].v);
mp[pii(s[i].u,s[i].v)]=s[i].len;
}
sort(s+,s+M+);
rep(i,,M){
int fu=find(s[i].u),fv=find(s[i].v);
if(fu!=fv){
mp[pii(s[i].u,s[i].v)]=;
fa[fu]=fv; add(s[i].u,s[i].v,s[i].len);
add(s[i].v,s[i].u,s[i].len); sum+=s[i].len;
}
}
dfs(,);
rep(i,,)
rep(j,,N){
f[j][i]=f[f[j][i-]][i-];
Mx[j][i]=max(Mx[j][i-],Mx[f[j][i-]][i-]);
}
scanf("%d",&Q);
rep(i,,Q){
scanf("%d%d",&u,&v); if(u>v) swap(u,v);
if(mp[pii(u,v)]==) printf("%d\n",sum);
else printf("%d\n",sum+mp[pii(u,v)]-query(u,v));
}
return ;
}
J .Jumping frog
题意:给定一个石头和水坑组成的环,顺时针依次是0到N-1;现在问对于K=[1,N-1],有多少个K满足,至少有一个点作为起点,每次顺时针跳到第K个点上,直到回到出发点,这个过程中不会跳到水坑中。
思路:对于K,我们直到他遍历的点和起点的距离的N/gcd(N,K)的倍数。 所以我们可枚举N/gcd(N,K);这个数是N的因子,数量比较少,对于每个因子,我们去暴力找即可。
还可以优化:如果k满足,那么k的倍数也满足。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
char c[maxn]; int fac[maxn],vis[maxn],tot,N,ans;
bool judge(int bg,int L)
{
int Now=bg;
while(true){
if(c[Now]=='P') return false;
Now=Now+L;
if(Now>=N) Now-=N;
if(Now==bg) break;
}
return true;
}
bool check(int L)
{
rep(i,,L-)
if(judge(i,L)) return true;
return false;
}
int main()
{
scanf("%s",c); N=strlen(c);
rep(i,,N-) if(N%i==) fac[++tot]=i;
rep(i,,tot) if(check(fac[i])) vis[fac[i]]=;
rep(i,,N-) ans+=vis[__gcd(i,N)];
printf("%d\n",ans);
return ;
}
Gym 101889:2017Latin American Regional Programming Contest(寒假自训第14场)的更多相关文章
- Gym.102006:Syrian Collegiate Programming Contest(寒假自训第11场)
学习了“叙利亚”这个单词:比较温和的一场:几何的板子eps太小了,坑了几发. A .Hello SCPC 2018! 题意:给定一个排列,问它是否满足,前面4个是有序的,而且前面4个比后面的都小. 思 ...
- Gym.101908 Brazil Subregional Programming Contest(寒假自训第六场)
这几天睡眠时间都不太够,室友晚上太会折腾了,感觉有点累,所以昨天的题解也没写,看晚上能不能补起来. B . Marbles 题意:给定N组数(xi,yi),玩家轮流操作,每次玩家可以选择其中一组对其操 ...
- 训练20191007 2017-2018 ACM-ICPC Latin American Regional Programming Contest
2017-2018 ACM-ICPC Latin American Regional Programming Contest 试题地址:http://codeforces.com/gym/101889 ...
- 2017-2018 ACM-ICPC Latin American Regional Programming Contest PART (11/13)
$$2017-2018\ ACM-ICPC\ Latin\ American\ Regional\ Programming\ Contest$$ \(A.Arranging\ tiles\) \(B. ...
- 2017-2018 ACM-ICPC Latin American Regional Programming Contest
题面pdfhttps://codeforc.es/gym/101889/attachments/download/7471/statements-2017-latam-regional.pdf zyn ...
- 2017-2018 ACM-ICPC Latin American Regional Programming Contest GYM101889
挺有意思的一套题,题也没有啥毒瘤了,本来是队切的结果种种原因大家全挂机了. 只补了百人题,一共7个,其他的暂时先不补了,,也不会嘛qwq H:签到 #include <bits/stdc++.h ...
- 2017-2018 ACM-ICPC Latin American Regional Programming Contest D.Daunting device
题意:一个数组n个操作每次先查询p颜色的数量然后求出区间,区间染色成x,然后求最大染色数 题解:odt裸题,多维护一个color个数数组就好了 //#pragma comment(linker, &q ...
- Gym.101955: Asia Shenyang Regional Contest(寒假自训第10场)
C.Insertion Sort 题意:Q次询问,每次给出N,M,Mod,问你有多少种排列,满足前面M个数字排序之后整个序列的LIS>=N-1. 思路:我们把数字看成[1,M],[N-M+1,N ...
- 2017-2018 ACM-ICPC Latin American Regional Programming Contest Solution
A - Arranging tiles 留坑. B - Buggy ICPC 题意:给出一个字符串,然后有两条规则,如果打出一个辅音字母,直接接在原字符串后面,如果打出一个元音字母,那么接在原来的字符 ...
随机推荐
- wine和cygwin安装使用教程
可以简单地认为wine和cygwin就是功能相反的两个东西.wine是linux的windows模拟环境,让linux可以运行windows程序:cygwin是windows的linux模拟环境,让w ...
- springmvc静态资源处理
1.配置springmvc拦截规则,注意不能拦截 /*,这样的话,会对所有请求默认拦截,而应该拦截 /, 这样servlet会先走默认的拦截规则,默认拦截规则找不到后,才会走 / 这个规则,这样静态资 ...
- JAVA工程师面试常见问题集锦
集锦一: 一.面试题基础总结 1. JVM结构原理.GC工作机制详解 答:具体参照:JVM结构.GC工作机制详解 ,说到GC,记住两点:1.GC是负责回收所有无任何引用对象的内存空间. 注意: ...
- [Codeforces708E]Student's Camp
Problem 一个n*m块砖的建筑,一共k天,每天风从两边吹,吹掉砖的概率为p,反之为1-p,求最终建筑没有倒塌的可能性(上层与下层有交集且每一层都有砖) Solution 首先,我们可以预处理出p ...
- shell脚本中出现图形化界面
http://www.ttlsa.com/shell/how-to-create-dialog-boxes-in-interactive-shell-script/
- Mysql 数据库意向锁意义
锁:对 “某种范围” 的数据上 “某种锁”1.“某种范围”:行.表 2.“某种锁”2.1 共享锁Shared Locks(S锁)1.兼容性:加了S锁的记录,允许其他事务再加S锁,不允许其他事务再加X锁 ...
- (C/C++学习笔记) 八. 程序控制语句
八. 程序控制语句 ● 基础知识 算法的基本控制结构: 顺序结构(sequential structure), 选择结构(case structure), 循环结构(loop structure) c ...
- (C/C++学习笔记) 一. 基础知识
一. 基础知识 ● 程序和C/C++ 程序: 根据Wirth (1976), Algorithms + Data Structures = Programs. Whence C: 1972, Denn ...
- 单元测试模拟-moq
1.moq 支持 net core 2.moq 通过一个接口类型 可以产生一个新的类 3.举例 //define interface to be mocked public interface ITe ...
- Docker小白从零入门实战
环境:Centos 6.9 0.查看是否满足安装需求. 先检查服务器环境,docker要求操作系统CentOS6以上,kernel 版本必须2.6.32-431或更高,即>=CentOS 6.5 ...