cf Round 587
A.Duff and Weight Lifting(思维)
显然题目中只有一种情况可以合并 2^a+2^a=2^(a+1)。
我们把给出的mi排序一下,模拟合并操作即可。
- # include <cstdio>
- # include <cstring>
- # include <cstdlib>
- # include <iostream>
- # include <vector>
- # include <queue>
- # include <stack>
- # include <map>
- # include <set>
- # include <cmath>
- # include <algorithm>
- using namespace std;
- # define lowbit(x) ((x)&(-x))
- # define pi acos(-1.0)
- # define eps 1e-
- # define MOD
- # define INF
- # define mem(a,b) memset(a,b,sizeof(a))
- # define FOR(i,a,n) for(int i=a; i<=n; ++i)
- # define FO(i,a,n) for(int i=a; i<n; ++i)
- # define bug puts("H");
- # define lch p<<,l,mid
- # define rch p<<|,mid+,r
- # define mp make_pair
- # define pb push_back
- typedef pair<int,int> PII;
- typedef vector<int> VI;
- # pragma comment(linker, "/STACK:1024000000,1024000000")
- typedef long long LL;
- int Scan() {
- int res=, flag=;
- char ch;
- if((ch=getchar())=='-') flag=;
- else if(ch>=''&&ch<='') res=ch-'';
- while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
- return flag?-res:res;
- }
- void Out(int a) {
- if(a<) {putchar('-'); a=-a;}
- if(a>=) Out(a/);
- putchar(a%+'');
- }
- const int N=;
- //Code begin...
- int a[N];
- int main ()
- {
- int n;
- scanf("%d",&n);
- FOR(i,,n) scanf("%d",a+i);
- sort(a+,a+n+);
- int now=a[], cnt=, ans=;
- FOR(i,,n) {
- if (now==a[i]) cnt++;
- else {
- while (now!=a[i]&&cnt>) {
- ++now;
- ans+=(cnt&);
- cnt/=;
- }
- if (now==a[i]) cnt++;
- else ans+=cnt, cnt=, now=a[i];
- }
- }
- while (cnt) ans+=(cnt&), cnt/=;
- printf("%d\n",ans);
- return ;
- }
B.Duff in Beach(DP)
这是一个计数问题。考虑DP。
考虑L<=n*k.
由于n*k<=1e6.我们把a数组变成b数组。令dp[i]表示以b[i]结尾的方法数。
那么dp[i]=sigma(上一段的数小于b[i]的dp[i])。
sigma我们可以用类似前缀和的办法维护一下。
考虑L>n*k.
此时数组太大不好直接构造,我们考虑把n*k的元素的最后n个数字平移到n*k后面的数字。
发现方法数是一样的。我们再统计每个数字可以平移多少次就OK了。
- # include <cstdio>
- # include <cstring>
- # include <cstdlib>
- # include <iostream>
- # include <vector>
- # include <queue>
- # include <stack>
- # include <map>
- # include <set>
- # include <cmath>
- # include <algorithm>
- using namespace std;
- # define lowbit(x) ((x)&(-x))
- # define pi acos(-1.0)
- # define eps 1e-
- # define MOD
- # define INF
- # define mem(a,b) memset(a,b,sizeof(a))
- # define FOR(i,a,n) for(int i=a; i<=n; ++i)
- # define FO(i,a,n) for(int i=a; i<n; ++i)
- # define bug puts("H");
- # define lch p<<,l,mid
- # define rch p<<|,mid+,r
- # define mp make_pair
- # define pb push_back
- typedef pair<int,int> PII;
- typedef vector<int> VI;
- # pragma comment(linker, "/STACK:1024000000,1024000000")
- typedef long long LL;
- int Scan() {
- int res=, flag=;
- char ch;
- if((ch=getchar())=='-') flag=;
- else if(ch>=''&&ch<='') res=ch-'';
- while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
- return flag?-res:res;
- }
- void Out(int a) {
- if(a<) {putchar('-'); a=-a;}
- if(a>=) Out(a/);
- putchar(a%+'');
- }
- const int N=;
- //Code begin...
- int to[N];
- LL dp[N], sum[N];
- PII a[N];
- int comp(const void * a, const void * b){return *(int *)a-*(int *)b;}
- int main ()
- {
- int n, k, cnt=;
- LL l, ans=;
- scanf("%d%lld%d",&n,&l,&k);
- FO(i,,n) a[i].first=Scan(), a[i].second=i;
- sort(a,a+n);
- to[a[].second]=++cnt;
- FO(i,,n) {
- if (a[i].first==a[i-].first) to[a[i].second]=cnt;
- else to[a[i].second]=++cnt;
- }
- int m=(l%n?l%n:n);
- FO(i,,min((LL)n*k,l)) {
- if (i && i%n==) {
- FOR(j,,cnt) sum[j]=;
- FO(j,i-n,i) sum[to[j%n]]=(sum[to[j%n]]+dp[j])%MOD;
- FOR(j,,cnt) sum[j]=(sum[j-]+sum[j])%MOD;
- }
- if (i<n) dp[i]=;
- else dp[i]=(+sum[to[i%n]])%MOD;
- ans=(ans+dp[i])%MOD;
- if (l>n*k && i>=n*k-n) ans=(ans+((l-i-)/n%MOD)*dp[i]%MOD)%MOD;
- }
- printf("%lld\n",ans);
- return ;
- }
C.Duff in the Army(LCA)
题目要求维护树的路径上的标号最小的a个数。(a<=10)
维护路径上的某些东西一般有LCT,LCA,树形DP,树链刨分,树分治。
由于题目允许离线,于是我们可以类似LCA预处理出一坨东西。
fa[x][i][]里面的是x节点到x节点的2^i个父亲中的标号最小的10个数。
合并的时候归并一下,最后求答案的时候就类似求LCA一样边爬边归并。
细节很多。
复杂度O((n+q)*logn).
- # include <cstdio>
- # include <cstring>
- # include <cstdlib>
- # include <iostream>
- # include <vector>
- # include <queue>
- # include <stack>
- # include <map>
- # include <set>
- # include <cmath>
- # include <algorithm>
- using namespace std;
- # define lowbit(x) ((x)&(-x))
- # define pi acos(-1.0)
- # define eps 1e-
- # define MOD
- # define INF
- # define mem(a,b) memset(a,b,sizeof(a))
- # define FOR(i,a,n) for(int i=a; i<=n; ++i)
- # define FO(i,a,n) for(int i=a; i<n; ++i)
- # define bug puts("H");
- # define lch p<<,l,mid
- # define rch p<<|,mid+,r
- # define mp make_pair
- # define pb push_back
- typedef pair<int,int> PII;
- typedef vector<int> VI;
- # pragma comment(linker, "/STACK:1024000000,1024000000")
- typedef long long LL;
- int Scan() {
- int res=, flag=;
- char ch;
- if((ch=getchar())=='-') flag=;
- else if(ch>=''&&ch<='') res=ch-'';
- while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
- return flag?-res:res;
- }
- void Out(int a) {
- if(a<) {putchar('-'); a=-a;}
- if(a>=) Out(a/);
- putchar(a%+'');
- }
- const int N=;
- //Code begin...
- struct Edge{int p, next;}edge[N<<];
- int head[N], cnt=;
- int bin[], fa[N][][], dep[N], temp[], ans[];
- VI node[N];
- void add_edge(int u, int v){edge[cnt].p=v; edge[cnt].next=head[u]; head[u]=cnt++;}
- void bin_init(){bin[]=; FO(i,,) bin[i]=bin[i-]<<;}
- void merge(int x, int nn)
- {
- int y=fa[x][nn-][], i=, j=, k=;
- while (k<=) {
- if (fa[x][nn-][i]== && fa[y][nn-][j]==) break;
- if (fa[x][nn-][i]==) fa[x][nn][k++]=fa[y][nn-][j++];
- else if (fa[y][nn-][j]==) fa[x][nn][k++]=fa[x][nn-][i++];
- else {
- fa[x][nn][k++]=min(fa[x][nn-][i], fa[y][nn-][j]);
- if (fa[x][nn-][i]<fa[y][nn-][j]) ++i;
- else ++j;
- }
- }
- }
- void merge_(int x, int nn)
- {
- int i=, j=, k=;
- mem(temp,);
- FOR(l,,) temp[l]=ans[l];
- mem(ans,);
- while (k<=) {
- if (fa[x][nn][i]==&&temp[j]==) break;
- if (fa[x][nn][i]==) ans[k++]=temp[j++];
- else if (temp[j]==) ans[k++]=fa[x][nn][i++];
- else {
- ans[k++]=min(fa[x][nn][i],temp[j]);
- if (fa[x][nn][i]<temp[j]) ++i;
- else if (fa[x][nn][i]>temp[j]) ++j;
- else ++i, ++j;
- }
- }
- }
- void dfs(int x, int fat)
- {
- fa[x][][]=fat;
- if (node[fat].size()) for (int i=; i<min((int)node[fat].size(),); ++i) fa[x][][i+]=node[fat][i];
- for (int i=; bin[i]<=dep[x]; ++i) fa[x][i][]=fa[fa[x][i-][]][i-][], merge(x,i);
- for (int i=head[x]; i; i=edge[i].next) {
- int v=edge[i].p;
- if (v==fat) continue;
- dep[v]=dep[x]+;
- dfs(v,x);
- }
- }
- void sol(int x, int y)
- {
- int l=, j=, k=;
- while (k<=) {
- if (l>=node[x].size()&&j>=node[y].size()) break;
- if (l>=node[x].size()) ans[k++]=node[y][j], ++j;
- else if (j>=node[y].size()) ans[k++]=node[x][l], ++l;
- else {
- ans[k++]=min(node[x][l],node[y][j]);
- if (node[x][l]<node[y][j]) ++l;
- else if (node[x][l]>node[y][j]) ++j;
- else ++l, ++j;
- }
- }
- if (dep[x]<dep[y]) swap(x,y);
- int t=dep[x]-dep[y];
- for (int i=; bin[i]<=t; ++i) if (bin[i]&t) merge_(x,i), x=fa[x][i][];
- for (int i=; i>=; --i) if (fa[x][i][]!=fa[y][i][]) merge_(x,i), merge_(y,i), x=fa[x][i][], y=fa[y][i][];
- if (x==y) return ;
- else {merge_(x,); return ;}
- }
- int main ()
- {
- bin_init();
- int n, m, q, u, v, a;
- scanf("%d%d%d",&n,&m,&q);
- FO(i,,n) scanf("%d%d",&u,&v), add_edge(u,v), add_edge(v,u);
- FOR(i,,m) scanf("%d",&u), node[u].pb(i);
- FOR(i,,n) sort(node[i].begin(),node[i].end());
- dfs(,);
- while (q--) {
- scanf("%d%d%d",&u,&v,&a);
- mem(ans,);
- sol(u,v);
- int mark;
- for (mark=; mark<=&&ans[mark]; ++mark) ;
- mark=min(mark-,a);
- printf("%d",mark);
- FOR(i,,mark) printf(" %d",ans[i]);
- putchar('\n');
- }
- return ;
- }
D.Duff in Mafia(待填坑)
E.Duff as a Queen(线段树+线性基)
给出一个数列(n<=2e5),有两种操作(q<=2e5)
1.给定区间[l,r]内的数都异或k。
2.询问区间[l,r]能够相互异或出几种数。
对于第2种操作,显然可以对区间[l,r]搞出线性基,答案就是1<<(线性基的个数).
注意到一个性质。
对于a1 a2 a3 ... an. 这些数的线性基等于 a1 a1^a2 a2^a3 ... an-1^an.的线性基。
大概就是由于这两个数列能够互相异或出来,于是能异或出来的数字种数都是相等的。
于是第一个操作就是 al^k al+1^k al+2^k ... ar^k.
对于线性基就是 al-1^a1^k a1^al+1 al+1^al+2 ... ar-1^ar ar^ar+1^k.
于是我们需要维护两个数列 一个原数列, 一个线性基与原数列相同的数列(次数列)
用BIT或者线段树维护原数列。
用线段树维护次数列的线性基。
答案即为所求。
- # include <cstdio>
- # include <cstring>
- # include <cstdlib>
- # include <iostream>
- # include <vector>
- # include <queue>
- # include <stack>
- # include <map>
- # include <set>
- # include <cmath>
- # include <algorithm>
- using namespace std;
- # define lowbit(x) ((x)&(-x))
- # define pi acos(-1.0)
- # define eps 1e-
- # define MOD
- # define INF
- # define mem(a,b) memset(a,b,sizeof(a))
- # define FOR(i,a,n) for(int i=a; i<=n; ++i)
- # define FO(i,a,n) for(int i=a; i<n; ++i)
- # define bug puts("H");
- # define lch p<<,l,mid
- # define rch p<<|,mid+,r
- # define mp make_pair
- # define pb push_back
- typedef pair<int,int> PII;
- typedef vector<int> VI;
- # pragma comment(linker, "/STACK:1024000000,1024000000")
- typedef long long LL;
- int Scan() {
- int res=, flag=;
- char ch;
- if((ch=getchar())=='-') flag=;
- else if(ch>=''&&ch<='') res=ch-'';
- while((ch=getchar())>=''&&ch<='') res=res*+(ch-'');
- return flag?-res:res;
- }
- void Out(int a) {
- if(a<) {putchar('-'); a=-a;}
- if(a>=) Out(a/);
- putchar(a%+'');
- }
- const int N=;
- //Code begin...
- int a[N], seg[N<<][], tree[N], n, q, ans[];
- void add(int x, int val){while (x<=n) tree[x]^=val, x+=lowbit(x);}
- int sum(int x){int ans=; while (x) ans^=tree[x], x-=lowbit(x); return ans;}
- void push_up(int p)
- {
- mem(seg[p],);
- FOR(c,,) seg[p][c]=seg[p<<][c];
- for (int c=; c>=; --c) {
- int x=seg[p<<|][c];
- for (int i=c; i>=; --i) {
- if (!(x>>i)) continue;
- if (!seg[p][i]) {seg[p][i]=x; break;}
- x^=seg[p][i];
- }
- }
- }
- void bulid(int p, int l, int r)
- {
- if (l==r) {
- for (int c=; c>=; --c) if (a[l]>>c) {seg[p][c]=a[l]; break;}
- return ;
- }
- int mid=(l+r)>>;
- bulid(lch); bulid(rch); push_up(p);
- }
- void update(int p, int l, int r, int L, int K)
- {
- if (L<l || L>r) return ;
- if (L==l && L==r) {
- a[L]^=K;
- mem(seg[p],);
- for (int c=; c>=; --c) if (a[L]>>c) {seg[p][c]=a[L]; break;}
- }
- else {
- int mid=(l+r)>>;
- update(lch,L,K); update(rch,L,K); push_up(p);
- }
- }
- void query(int p, int l, int r, int L, int R)
- {
- if (R<l || L>r) return ;
- if (L<=l && R>=r) {
- for (int i=; i>=; --i) {
- int x=seg[p][i];
- for (int c=i; c>=; --c) {
- if (!(x>>c)) continue;
- if (!ans[c]) {ans[c]=x; break;}
- x^=ans[c];
- }
- }
- }
- else {
- int mid=(l+r)>>;
- query(lch,L,R), query(rch,L,R);
- }
- }
- int main ()
- {
- int flag, l, r, k;
- scanf("%d%d",&n,&q);
- FOR(i,,n) scanf("%d",a+i);
- for (int i=n; i>=; --i) a[i]^=a[i-], add(i,a[i]);
- bulid(,,n);
- while (q--) {
- scanf("%d%d%d",&flag,&l,&r);
- if (flag==) {
- scanf("%d",&k);
- update(,,n,l,k); add(l,k);
- if (r!=n) update(,,n,r+,k), add(r+,k);
- }
- else {
- mem(ans,);
- if (l!=r) query(,,n,l+,r);
- int temp=sum(l);
- for (int i=; i>=; --i) {
- if (!(temp>>i)) continue;
- if (!ans[i]) {ans[i]=temp; break;}
- temp^=ans[i];
- }
- int cnt=;
- FOR(i,,) if (ans[i]) ++cnt;
- printf("%d\n",<<cnt);
- }
- }
- return ;
- }
F.Duff is Mad(待填坑)
cf Round 587的更多相关文章
- 【二分】CF Round #587 (Div. 3)E2 Numerical Sequence (hard version)
题目大意 有一个无限长的数字序列,其组成为1 1 2 1 2 3 1.......1 2 ... n...,即重复的1~1,1~2....1~n,给你一个\(k\),求第\(k(k<=10^{1 ...
- CF Round #551 (Div. 2) D
CF Round #551 (Div. 2) D 链接 https://codeforces.com/contest/1153/problem/D 思路 不考虑赋值和贪心,考虑排名. 设\(dp_i\ ...
- CF Round #510 (Div. 2)
前言:没想到那么快就打了第二场,题目难度比CF Round #509 (Div. 2)这场要难些,不过我依旧菜,这场更是被\(D\)题卡了,最后\(C\)题都来不及敲了..最后才\(A\)了\(3\) ...
- UOJ #30. [CF Round #278] Tourists
UOJ #30. [CF Round #278] Tourists 题目大意 : 有一张 \(n\) 个点, \(m\) 条边的无向图,每一个点有一个点权 \(a_i\) ,你需要支持两种操作,第一种 ...
- 竞赛题解 - CF Round #524 Div.2
CF Round #524 Div.2 - 竞赛题解 不容易CF有一场下午的比赛,开心的和一个神犇一起报了名 被虐爆--前两题水过去,第三题卡了好久,第四题毫无头绪QwQ Codeforces 传送门 ...
- 【前行&赛时总结】◇第4站&赛时9◇ CF Round 513 Div1+Div2
◇第4站&赛时9◇ CF Round 513 Div1+Div2 第一次在CF里涨Rating QWQ 深感不易……作blog以记之 ( ̄▽ ̄)" +Codeforces 的门为你打 ...
- CF Round #600 (Div 2) 解题报告(A~E)
CF Round #600 (Div 2) 解题报告(A~E) A:Single Push 采用差分的思想,让\(b-a=c\),然后观察\(c\)序列是不是一个满足要求的序列 #include< ...
- CF Round #580(div2)题解报告
CF Round #580(div2)题解报告 T1 T2 水题,不管 T3 构造题,证明大约感性理解一下 我们想既然存在解 \(|a[n + i] - a[i]| = 1\) 这是必须要满足的 既然 ...
- CF round #622 (div2)
CF Round 622 div2 A.简单模拟 B.数学 题意: 某人A参加一个比赛,共n人参加,有两轮,给定这两轮的名次x,y,总排名记为两轮排名和x+y,此值越小名次越前,并且对于与A同分者而言 ...
随机推荐
- 北京Uber优步司机奖励政策(1月25日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- DBoW2 词袋模型笔记
DBoW算法用于解决Place Recognition问题,ORB-SLAM,VINS-Mono等SLAM系统中的闭环检测模块均采用了该算法.来源于西班牙的Juan D. Tardos课题组. 主要是 ...
- 用wireshark查看 tcpdump 抓取的mysql交互数据
用tcpdump 抓取 mysql客户端与服务器端的交互 1开启tcpdump tcpdump -i eth0 -s 3000 port 3306 -w ~/sql.pcap 先故意输入一个错误的密 ...
- WeTest功能优化第3期:业内首创,有声音的云真机
第3期功能优化目录 [云真机远程调试]音频同步传输实现测试有声 [兼容性测试报告]新增视频助力动态定位问题 [云真机远程调试]菜单栏优化助力机型选择 本期介绍的新功能,秉承创造用户需求的理念,在云真机 ...
- Java基础知识总结一
1.何为编程? 编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程. 为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路.方法.和手段通过计算机能够理解 ...
- 小程序页面的四种文件(JSON、WXML、WXSS、JS)加载顺序
一个小程序页面由四种文件组成: 1)json 页面配置文件 2)js 页面逻辑文件(必需) 3)wxml 页面结构文件(必需) 4)wxss 页面样式文件 这四个文件的加载顺序: 第一步: 加载页面j ...
- leetcode-峰值检测
寻找峰值 峰值元素是指其值大于左右相邻值的元素. 给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引. 数组可能包含多个峰值,在这种情况下,返回 ...
- [转载]CENTOS 6.0 iptables 开放端口80 3306 22端口
原文地址:6.0 iptables 开放端口80 3306 22端口">CENTOS 6.0 iptables 开放端口80 3306 22端口作者:云淡风轻 #/sbin/iptab ...
- Python 学习笔记之——用 sklearn 对数据进行预处理
1. 标准化 标准化是为了让数据服从一个零均值和单位方差的标准正态分布.也即针对一个均值为 \(mean\) 标准差为 \(std\) 的向量 \(X\) 中的每个值 \(x\),有 \(x_{sca ...
- solidity python 签名和验证
注意,以太坊智能合约里面采用的是公钥非紧凑类型 def gen_secrets_pair(): """ 得到公钥和私钥 :return: ""&quo ...