Codeforces Round# 305 (Div 1)
#include <bits/stdc++.h> #define maxn 1000010
using namespace std;
typedef long long ll;
bool vis[maxn];
int md, h, a, x, y; int Go(int h, int x, int y){
memset(vis, 0, sizeof vis);
int cnt = 0;
while(true){
if(vis[h])
return -1;
vis[h] = 1;
h = (1ll * h * x + y) % md;
++ cnt;
if(h == a)
return cnt;
}
} int main(){
scanf("%d", &md);
scanf("%d%d%d%d", &h, &a, &x, &y);
int a1 = Go(h, x, y), b1 = Go(a, x, y);
scanf("%d%d%d%d", &h, &a, &x, &y);
int a2 = Go(h, x, y), b2 = Go(a, x, y);
if(a1 == -1 || a2 == -1)return puts("-1"), 0;
if(b1 == -1 && b2 == -1){
if(a1 == a2)printf("%d\n", a1);
else printf("-1\n");
return 0;
}
if(b1 != -1 && b2 != -1){
for(int i = 0; i <= md; i ++){
if(a1 + 1ll * b1 * i >= a2 && (a1 + 1ll * b1 * i - a2) % b2 == 0){
cout << a1 + 1ll * b1 * i << endl;
return 0;
}
}return puts("-1"), 0;
}
else{
if(b1 == -1)swap(a1, a2), swap(b1, b2);
if(a2 >= a1 && (a2 - a1) % b1 == 0)
printf("%d\n", a2);
else return puts("-1"), 0;
}
return 0;
}
题目大意: 就是给你一个序列,定义f(x)为(所有区间长度为x的最小值)的最大值,输出f(1)....f(n)
n ≤ 2 * 10^5
Sol:感觉用并查集就可以水。。
#include <bits/stdc++.h>
#define maxn 200010
using namespace std; int n;
int a[maxn]; int fa[maxn];
int getfa(int x){return x == fa[x] ? x : fa[x] = getfa(fa[x]);} int h[maxn]; bool cmp(int i, int j){
if(a[i] == a[j]) return i < j;
return a[i] < a[j];
} int t; int size[maxn], f[maxn];
inline void update(int x){
fa[x] = x, size[x] = 1;
if(t = getfa(x-1))fa[t] = x, size[x] += size[t];
if(t = getfa(x+1))fa[t] = x, size[x] += size[t];
f[size[x]] = max(f[size[x]], a[x]);
return;
} int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &a[i]), h[i] = i;
sort(h+1, h+1+n, cmp); for(int i = n; i >= 1; i --)
update(h[i]);
for(int i = n; i >= 1; i --)
f[i] = max(f[i+1], f[i]); for(int i = 1; i <= n; i ++)
printf("%d ", f[i]);
return 0;
}
题目大意:给定一个序列,初始为空,每次从序列中选出一个数字添加或删除,求gcd(Ai, Aj) = 1的有序数对(i, j)的个数。
容斥原理。
#include <bits/stdc++.h>
#define maxn 1000010
using namespace std; int N, Q; int A[maxn]; vector<int> P[maxn]; bool vis[maxn];
int p[maxn], primes, mn[maxn]; void prepare(){
mn[1] = 1;
int N = 500000;
for(int i = 2; i <= N; i ++){
if(!vis[i]){
p[primes ++] = i;
mn[i] = i;
}
for(int j = 0; j < primes; j ++){
if(1ll * i * p[j] > N)break;
vis[i * p[j]] = true;
if(i % p[j] == 0){mn[i * p[j]] = p[j];break;}
mn[i * p[j]] = mn[i];
}
}
} void FJ(int Id, int A){
while(A != 1){
int now = mn[A];
while(A % now == 0)
A /= now;
P[Id].push_back(now);
}
} long long ans; int Bits[100], cnt[maxn]; void update(int Id, int val){
int n = P[Id].size(), S = (1 << n) - 1;
for(int i = 0; i <= S; i ++){
long long LCM = 1;
for(int j = 0; j < n; j ++)
if(i >> j & 1)
LCM = LCM * P[Id][j];
cnt[LCM] += val;
}
} int QAQ(int S, int now){
int n = P[now].size();
long long ret = 0, LCM = 1;
for(int i = 0; i < n; i ++)
if(S >> i & 1)
LCM = LCM * P[now][i];
return cnt[LCM];
} long long work(int now){
int n = P[now].size();
int S = (1 << n) - 1;
long long ret = 0;
for(int i = 0; i <= S; i ++)
if(Bits[i] & 1)ret -= QAQ(i, now);
else ret += QAQ(i, now);
return ret;
} void solve(int Id){
if(vis[Id])update(Id, -1), ans -= work(Id);
else ans += work(Id), update(Id, 1);
vis[Id] ^= 1;
} int main(){
prepare();
for(int i = 1; i < 1<<6; i ++)
Bits[i] = __builtin_popcount(i);
scanf("%d%d", &N, &Q);
for(int i = 1; i <= N; i ++)
scanf("%d", &A[i]);
for(int i = 1; i <= N; i ++)
FJ(i, A[i]);
memset(vis, 0, sizeof vis);
int Id;
for(int i = 1; i <= Q; i ++){
scanf("%d", &Id);
solve(Id);
printf("%I64d\n", ans);
}
return 0;
}
题目大意:平面上有n个点,你需要给他们一一染色,可以染'b'(blue)或'r'(red),要求每一行和每一列所染色的(红色-蓝色)数目的绝对值<=1,输出染色方案。
n ≤ 2 * 10^5
QAQ虽然说一看就知道是网络流但是数据范围也是吓我一跳QAQ
然而YY半天建图无果。。
首先行和列示要看成点的,给的每一个点(x, y)看成一条边无疑,容量为1
然后广告犇提出了限流思想:既然每行或每列不能相差超过1,那么就可以从源点->每一行连接容量为(cntx[i] / 2)的边,这样红蓝就一定符合条件了!(其中cntx[i]表示第i行有多少个点),从每一列连向汇点同理QAQ
但是这样输出的方案可能还不够,有一些点仍然没有确定怎么办?(假如某一行某一列的点的个数为奇数。。)
然后就弃疗了
orz了一下神犇的题解(虽然说并不知道神犇是谁,但是网络流竟然可以过QAQ)
先把行列离散化一下QAQ,然后如上建边,然后跑一边最大流,然后如果有多出来的就再添加一条容量为1的边,再跑一遍最大流。最后如果割掉了(edge[i<<1])说明此点和S相连,否则和T相连。
某犇:我快YY出正解了
主要程序:(网络流就不写了QAQ)
int main(){
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d%d", &x[i], &y[i]);
for(int i = 1; i <= n; i ++)
++ cx[x[i]], ++ cy[y[i]];
int id = 0;
for(int i = 1; i <= 200000; i ++)
if(cx[i])Idx[i] = ++ id;
for(int i = 1; i <= 200000; i ++)
if(cy[i])Idy[i] = ++ id;
T = id + 1;
for(int i = 1; i <= n; i ++)
add(Idx[x[i]], Idy[y[i]], 1);
for(int i = 1; i <= 200000; i ++)
if(cx[i] > 1) add(S, Idx[i], cx[i] >> 1);
for(int i = 1; i <= 200000; i ++)
if(cy[i] > 1) add(Idy[i], T, cy[i] >> 1); Dinic();
for(int i = 1; i <= 200000; i ++)
if(cx[i] & 1) add(S, Idx[i], 1);
for(int i = 1; i <= 200000; i ++)
if(cy[i] & 1) add(Idy[i], T, 1);
Dinic();
for(int i = 1; i <= n; i ++)
if(!edge[i<<1].w)
putchar('b');
else putchar('r');
puts("");
return 0;
}
给出一大堆字符串,每次询问第k个串在第l~r的串中作为子串出现了多少次
简述:AC自动机(failtree)的dfs序做可持久化。
#include <bits/stdc++.h>
#define maxn 200010
using namespace std; int n, m; char str[maxn]; int tr[maxn][26], root, smz; int pos[maxn]; struct Edge{
int to, nxt;
}edge[maxn];
int h[maxn], cnt;
void add(int u, int v){
cnt ++;
edge[cnt].to = v;
edge[cnt].nxt = h[u];
h[u] = cnt;
} void init(){
memset(tr, -1, sizeof tr);
root = smz = 0;
} void Insert(int Id){
int N = strlen(str+1), now = root;
for(int i = 1; i <= N; i ++){
int c = str[i] - 'a';
if(tr[now][c] == -1)tr[now][c] = ++ smz;
now = tr[now][c];
}
pos[Id] = now;
} queue<int> Q; int fa[maxn], fail[maxn];
void buildfail(){
for(int i = 0; i < 26; i ++)
if(tr[root][i] == -1) tr[root][i] = root;
else fail[tr[root][i]] = root, Q.push(tr[root][i]), fa[tr[root][i]] = root;
while(!Q.empty()){
int u = Q.front(); Q.pop();
for(int i = 0; i < 26; i ++){
if(tr[u][i] == -1)tr[u][i] = tr[fail[u]][i];
else fail[tr[u][i]] = tr[fail[u]][i], Q.push(tr[u][i]), fa[tr[u][i]] = u;
}
}
for(int i = 1; i <= smz; i ++)
add(fail[i], i);
} int In[maxn], Out[maxn], dfs_clock; void dfs(int u){
In[u] = ++ dfs_clock;
for(int i = h[u]; i; i = edge[i].nxt)
dfs(edge[i].to);
Out[u] = dfs_clock;
} #define M 10000010
int T[maxn], L[M], R[M], val[M]; int size; int build(int l, int r){
if(l > r) return 0;
int now = ++ size;
int mid = l + r >> 1;
L[now] = build(l, mid - 1);
R[now] = build(mid + 1, r);
return now;
} int update(int rt, int pos, int l, int r){
int mid = l + r >> 1, now = ++ size;
L[now] = L[rt], R[now] = R[rt], val[now] = val[rt] + 1;
if(l == r) return now;
if(pos <= mid)L[now] = update(L[rt], pos, l, mid);
else R[now] = update(R[rt], pos, mid + 1, r);
return now;
} int ask(int rt, int al, int ar, int l, int r){
if(al == l && ar == r)return val[rt];
int mid = l + r >> 1;
if(ar <= mid)return ask(L[rt], al, ar, l, mid);
if(al > mid) return ask(R[rt], al, ar, mid + 1, r);
return ask(L[rt], al, mid, l, mid) + ask(R[rt], mid + 1, ar, mid + 1, r);
} int main(){
init();
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i ++)
scanf("%s", str+1), Insert(i);
buildfail();
dfs(root);
T[0] = build(1, dfs_clock);
for(int i = 1; i <= n; i ++){
T[i] = T[i-1];
for(int j = pos[i]; j; j = fa[j])
T[i] = update(T[i], In[j], 1, dfs_clock);
} int l, r, k;
for(int i = 1; i <= m; i ++){
scanf("%d%d%d", &l, &r, &k); l --;
printf("%d\n", ask(T[r], In[pos[k]], Out[pos[k]], 1, dfs_clock) - ask(T[l], In[pos[k]], Out[pos[k]], 1, dfs_clock));
}
return 0;
} /*
5 5
a
ab
abab
ababab
b
1 5 1
3 5 1
1 5 2
1 5 3
1 4 5
*/
Codeforces Round# 305 (Div 1)的更多相关文章
- set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet
题目传送门 /* 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 查找左右相 ...
- 数论/暴力 Codeforces Round #305 (Div. 2) C. Mike and Frog
题目传送门 /* 数论/暴力:找出第一次到a1,a2的次数,再找到完整周期p1,p2,然后以2*m为范围 t1,t2为各自起点开始“赛跑”,谁落后谁加一个周期,等到t1 == t2结束 详细解释:ht ...
- 暴力 Codeforces Round #305 (Div. 2) B. Mike and Fun
题目传送门 /* 暴力:每次更新该行的num[],然后暴力找出最优解就可以了:) */ #include <cstdio> #include <cstring> #includ ...
- 字符串处理 Codeforces Round #305 (Div. 2) A. Mike and Fax
题目传送门 /* 字符串处理:回文串是串联的,一个一个判断 */ #include <cstdio> #include <cstring> #include <iostr ...
- Codeforces Round #305 (Div. 2) B. Mike and Fun 暴力
B. Mike and Fun Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/548/pro ...
- Codeforces Round #305 (Div. 2) A. Mike and Fax 暴力回文串
A. Mike and Fax Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/548/pro ...
- Codeforces Round #305 (Div. 1) B. Mike and Feet 单调栈
B. Mike and Feet Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/pro ...
- Codeforces Round #305 (Div. 1) A. Mike and Frog 暴力
A. Mike and Frog Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/547/pr ...
- 「日常训练」Mike and Feet(Codeforces Round #305 Div. 2 D)
题意 (Codeforces 548D) 对一个有$n$个数的数列,我们要求其连续$x(1\le x\le n)$(对于每个$x$,这样的连续group有若干个)的最小数的最大值. 分析 这是一道用了 ...
随机推荐
- Java面向对象的封装
封装是Java面向对象的三大特性之一,通常我们是通过包管理机制同时对类进行封装,隐藏其内部实现细节,通常开发中不允许直接操作类中的成员属性,所以属性一般设置为私有权限private,类中一般会给出一些 ...
- 【USACO】calfflac
关键:以回文中心位置为变量进行遍历 //必须把纯字母先提出来 否则肯能会出现错误 比如: lvlv= 在检查长度4时 lvlv认为不是回文 vlv=认为是回文 但实际上 lvl 出现的要更早一些 // ...
- 用Navicat for oracle导入现有数据库
重要参考:http://www.admin5.com/article/20130420/499241.shtml 前期准备,参考另一篇随笔. 安装Oracle,PL/SQL, 新建表空间myTS,新建 ...
- [MAC ] Mac-OSX下安装Git
转载自 : http://www.cnblogs.com/shanyou/archive/2011/01/30/1948088.html Mac-OSX下安装Git是一件很简单的事,我们可以下载一个安 ...
- Jam的计数法(codevs 1140)
题目描述 Description Jam是个喜欢标新立异的科学怪人.他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩.在他的计数法中,每个数字的位数都是相同的(使用 ...
- stm32——Flash读写
stm32——Flash读写 一.Flash简介 通过对stm32内部的flash的读写可以实现对stm32的编程操作. stm32的内置可编程Flash在许多场合具有十分重要的意义.如其支持ICP( ...
- WebService之CXF框架
本文主要包括以下内容 ant工具的使用 利用cxf实现webservice cxf与spring整合 ajax访问webservice ant 工具 1.为什么要用到ant这个工具呢? Ant做为一种 ...
- exit()与_exit()函数的区别(Linux系统中)
注:exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出,一般都用-1或者1,标准C里有EXIT_SUCCESS和EXIT_FAILURE两个宏,用exit(EXI ...
- MQ的通讯模式
1) 点对点通讯:点对点方式是最为传统和常见的通讯方式,它支持一对一.一对多.多对多.多对一等多种配置方式,支持树状.网状等多种拓扑结构. 2) 多点广播:MQ适用于不同类型的应用.其中重要的,也是正 ...
- 随机sample文件Python程序
经常遇到由于样本巨大,需要sample一部分文件进行案例分析的情况,下面的程序主要为了随机抽取一个大文件中的N行. #!/usr/bin/python # -*- coding: <encodi ...