[Codeforces 547A]

#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;
}

  

[Codeforces 547B]

题目大意: 就是给你一个序列,定义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;
}

[Codeforces 547C]

题目大意:给定一个序列,初始为空,每次从序列中选出一个数字添加或删除,求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;
}

  

[Codeforces 547D]

题目大意:平面上有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;
}

[Codeforces 547E]

大爷题解传送门

给出一大堆字符串,每次询问第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)的更多相关文章

  1. set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet

    题目传送门 /* 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 查找左右相 ...

  2. 数论/暴力 Codeforces Round #305 (Div. 2) C. Mike and Frog

    题目传送门 /* 数论/暴力:找出第一次到a1,a2的次数,再找到完整周期p1,p2,然后以2*m为范围 t1,t2为各自起点开始“赛跑”,谁落后谁加一个周期,等到t1 == t2结束 详细解释:ht ...

  3. 暴力 Codeforces Round #305 (Div. 2) B. Mike and Fun

    题目传送门 /* 暴力:每次更新该行的num[],然后暴力找出最优解就可以了:) */ #include <cstdio> #include <cstring> #includ ...

  4. 字符串处理 Codeforces Round #305 (Div. 2) A. Mike and Fax

    题目传送门 /* 字符串处理:回文串是串联的,一个一个判断 */ #include <cstdio> #include <cstring> #include <iostr ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 「日常训练」Mike and Feet(Codeforces Round #305 Div. 2 D)

    题意 (Codeforces 548D) 对一个有$n$个数的数列,我们要求其连续$x(1\le x\le n)$(对于每个$x$,这样的连续group有若干个)的最小数的最大值. 分析 这是一道用了 ...

随机推荐

  1. Linux tcp_wrappers 详解

    tcp_wrappers是linux中一个安全机制[TCP_wrappers防火墙],一定程度上限制某种服务的访问权限,达到了保护系统的目的一. 要想用好tcp_wrappers,首先检查某种服务是否 ...

  2. django-cms 代码研究(七)杂七杂八

    实体关系图 核心对象: cms_page/cms_placeholder/cms_cmsplugin. page模型类继承关系图 CMSPlugin&Placeholder模型类继承关系图 = ...

  3. ENGINE=InnoDB

    最开始用MySQL Administrator建数据库的时候,表缺省是InnoDB类型,也就没有在意.后来用Access2MySQL导数据的时候发现只能导成 MyISAM类型的表 区别如下原来是MyI ...

  4. 更改SharePoint 2010 顶部导航为下拉菜单样式

      更改SharePoint 2010 顶部导航为下拉菜单样式 最后的效果图: 假如一个网站集顶级站点下面有子网站:sub site1,该子站点下面又有两个子站点:sub site1_1,sub si ...

  5. Java for LeetCode 145 Binary Tree Postorder Traversal

    Given a binary tree, return the postorder traversal of its nodes' values. For example: Given binary ...

  6. 【回溯】n皇后问题

    问题 U: [回溯]n皇后问题 时间限制: 1 Sec  内存限制: 128 MB提交: 4  解决: 4[提交][状态][讨论版] 题目描述 在一个国际象棋棋盘上,放置n个皇后(n<10),使 ...

  7. HDU2050离散数学折线分割平面

    折线分割平面 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  8. VS添加lib库

    #pragma comment(lib,"opengl32.lib")

  9. BaseColumns以及自定义Column

    android provider 包下自带的BaseColumn /* * Copyright (C) 2006 The Android Open Source Project * * License ...

  10. (十)stm32中FSMC的使用(用于LCD)

    FSMC全称“静态存储器控制器”. 使用FSMC控制器后,可以把FSMC提供的FSMC_A[25:0]作为地址线,而把FSMC提供的FSMC_D[15:0]作为数据总线. (1)当存储数据设为8位时, ...