# 刷题日记

## 2016-12-26

Codeforces Round #383 (Div. 1)
A. Arpa’s loud Owf and Mehrdad’s evil plan

Codeforces Round #372 (Div. 1)
B. Complete The Graph

bzoj 1576安全路径

Q：为什么是对的？
A：因为最终答案只取决于最小值，用最小值更新它之后就不用再考虑这个点了。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i; i = edge[i].next)
#define fl edge[i].f
#define vfl edge[i ^ 1].f

using namespace std;
const int N = 200005;
const int M = 200005;
struct Edge{int next,to,w;}edge[M << 1];
struct ed{int a,b,val;}e[M];
bool vis[N];
priority_queue<pair<int,int> >q;
int dfs(int x){if(dep[x])return dep[x];return dep[x] = (dfs(fa[x]) + 1);}
int find(int x,int y,int z)
{
if(x == y)return x;
if(dep[x] < dep[y])swap(x,y);
if(!re[x])re[x] = z - dis[x];
fa[x] = find(fa[x],y,z);
}
bool cmp(ed a,ed b){return a.val < b.val;}
#define mp make_pair
#define sec second
void dij()
{
q.push(mp(0,1));
while(!q.empty())
{
int x = q.top().sec;q.pop();
if(vis[x])continue;vis[x] = 1;
RepG(i,x)if(dis[v] > dis[x] + edge[i].w)dis[v] = dis[x] + edge[i].w,q.push(mp(-dis[v],v)),fa[v] = x;
}
}
int main()
{
scanf("%d%d",&n,&m);
Rep(i,m)
{
scanf("%d%d%d",&A[i],&B[i],&C[i]);
save(A[i],B[i],C[i]);
save(B[i],A[i],C[i]);
}
Rep(i,n)dis[i] = 2e9;
dis[1] = 0;dij();
dep[1] = 1;rep(i,2,n)dep[i] = dfs(i);
Rep(i,m)
{
if(dis[A[i]] + C[i] == dis[B[i]] || dis[A[i]] - C[i] == dis[B[i]])continue;
e[++ ent] = (ed){A[i],B[i],dis[A[i]] + dis[B[i]] + C[i]};
}
sort(e + 1,e + 1 + ent,cmp);
Rep(i,ent)find(e[i].a,e[i].b,e[i].val);
rep(i,2,n)printf("%d\n",re[i] == 0 ? -1 : re[i]);
return 0;
}

1108: [POI2007]天然气管道Gaz
Description
Mary试图控制成都的天然气市场。专家已经标示出了最好的天然气井和中转站在成都的地图。现在需要将中转

Input
第一行为一个正整数n(2<=n<=50000)，表示天然气井的数量（中转站的数量与之相等）。接下来n行，每行两

Output
第一行包含一个数，表示最短的连接管道长度。
orzfsf！实际上把式子写出来直接算就行了。

#include <cstdio>
int n;
int main() {
scanf("%d", &n);
long long ans = 0;
int x, y;
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &x, &y);
ans += y - x;
}
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &x, &y);
ans += x - y;
}
printf("%lld\n", ans);
return 0;
}

1115: [POI2009]石子游戏Kam
Description

Input

Output
u行，若先手必胜输出TAK，否则输出NIE。

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i; i = edge[i].next)
#define fl edge[i].f
#define vfl edge[i ^ 1].f

using namespace std;
const int N = 1005;
int n,m,a[N],b[N];
int main()
{
scanf("%d",&m);
while(m --)
{
scanf("%d",&n);
int re = 0;
Rep(i,n)scanf("%d",&a[i]);
b[1] = a[1];
rep(i,2,n)b[i] = a[i] - a[i - 1];
for(int i = n;i > 0;i -= 2)re ^= b[i];
puts(!re ? "NIE" : "TAK");
}
return 0;
}

## 2016-12-17

bzoj 1150: [CTSC2007]数据备份Backup

Q:删了x和z，然而堆里还有一些东西的next指针为x(pre == z)？
A:在删除的时候把全局的结构体改一改，在弹堆顶的时候，把那个位置的元素取出来，而不用当前在堆里的元素，这样指针部分就不会出问题了。

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
typedef long long LL;
const LL inf = 1ll << 60;
const int N = 100005;
LL ans;
bool del[N];
struct Node
{
LL val;
int next,pre,id;
}t[N];
bool operator < (Node A,Node B){return A.val > B.val;}
priority_queue<Node>q;
void Del(Node &x) //更新为反悔节点
{
del[x.pre] = del[x.next] = 1;
x.val = min(inf,t[x.pre].val + t[x.next].val - x.val);
x.pre = t[x.pre].pre;
t[x.pre].next = x.id;
x.next = t[x.next].next;
t[x.next].pre = x.id;//更新全局数组
t[x.id] = x;
}
int last,now,n,m;
int main()
{
scanf("%d%d",&n,&m);
Rep(i,n)
{
scanf("%d",&now);
t[i].val = now - last;
t[i].pre = i - 1;
t[i].next = i + 1;
t[i].id = i;
last = now;
}
t[1].val = inf,t[n + 1].val = inf,t[n + 1].id = n + 1,t[n + 1].pre = n;
Rep(i,n + 1)q.push(t[i]);
while(m --)
{
while(del[q.top().id])q.pop();
Node x = q.top();
q.pop();
//这时候需要把x变成t[x],因为它的next和pre指针变了。
x = t[x.id];
ans += x.val;
Del(x);
q.push(x);
}
printf("%lld\n",ans);
return 0;
}

bzoj 2563: 阿狸和桃子的游戏

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
typedef long long LL;
const int N = 20005;
LL val[N];
int n,m;
int main()
{
scanf("%d%d",&n,&m);
Rep(i,n)scanf("%lld",&val[i]),val[i] *= 2;
Rep(i,m)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
val[a] += c,val[b] += c;
}
sort(val + 1,val + 1 + n);
LL a = 0,b = 0;
Rep(i,n)
{
if(i & 1)a += val[i];
else b += val[i];
}
printf("%lld\n",(b - a) / 2);
return 0;
}

bzoj 1116: [POI2008]CLO

Description
Input

Output
TAK或者NIE 常做POI的同学,应该知道这两个单词的了…

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
const int N = 200005;
int fa[N],n,m;
bool tag[N];
int find(int x){return fa[x] == x ? x : fa[x] = find(fa[x]);}
int main()
{
scanf("%d%d",&n,&m);
Rep(i,n)fa[i] = i;
Rep(i,m)
{
int a,b;
scanf("%d%d",&a,&b);
if(find(a) == find(b))
tag[find(a)] = 1;
else
{
int tx = find(a),ty = find(b);
if(tag[tx])tag[ty] = 1;
fa[tx] = ty;
}
}
bool ans = 1;
Rep(i,n)ans &= tag[find(i)];
puts(ans ? "TAK" : "NIE");
return 0;
}

51Nod 1577
L,R$L,R$之间是不是能选出一些数字异或起来等于K.

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
{
int ans = 0;char ch = getchar();
while(ch > '9' || ch < '0')ch = getchar();
while(ch >= '0' && ch <= '9')ans = ans * 10 + ch - '0',ch = getchar();
return ans;
}
const int N = 100005;
int n,m,a[N];
struct Node
{
int val[30],id[30];
int &operator [](int x){return val[x];}
void ins(int x,int y)
{
for(int i = 29;~ i;-- i)
{
if(x & (1 << i) && val[i])
{
if(id[i] > y)swap(x,val[i]),swap(y,id[i]);
x ^= val[i];
}
else if(x & (1 << i)){val[i] = x;id[i] = y;break;}
}
}
bool check(int x,int R)
{
int mx = 0;
for(int i = 29;~ i;-- i)
if(x & (1 << i))x ^= val[i],mx = max(mx,id[i]);
return (!x) && mx <= R;
}
}f[N];
int main()
{
Dwn(i,n)
{
f[i] = f[i + 1];
f[i].ins(a[i],i);
}
Rep(i,m)
{
int L,R,K;
puts(f[L].check(K,R) ? "YES" : "NO");
}
return 0;
}

Div1 278 C. Prefix Product Sequence

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i; i = edge[i].next)
#define fl edge[i].f
#define vfl edge[i ^ 1].f

using namespace std;
int n,m;
int vis[100005];
int rev(int x,int p){int tmp = 1;while(p){if(p & 1)tmp = 1ll * tmp * x % n;p >>= 1;x = 1ll * x * x % n;}return tmp;}
int main()
{
scanf("%d",&n);
int cur = 1;
if(n != 1 && n != 4)for(int i = 2;i * i <= n;++ i)if(n % i == 0)return puts("NO"),0;
puts("YES");
if(n == 1)puts("1");
else if(n == 4)printf("1\n3\n2\n4\n");
else
{
puts("1");
for(int i = 2;i < n;++ i)
printf("%d\n",1ll * i * rev(i - 1,n - 2) % n);
printf("%d\n",n);
}
return 0;
}


45min不到就写完了……然后就去复习会考去了QAQ

2901: 矩阵求和

mn可过。

i=acj=bdk=1na[i][k]b[k][j]

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i; i = edge[i].next)
#define fl edge[i].f
#define vfl edge[i ^ 1].f

using namespace std;
int n,m;
const int N = 2005;
typedef long long LL;
{
int x = 0;
char ch = getchar();
while(ch > '9' || ch < '0')ch = getchar();
while(ch >= '0' && ch <= '9')x = 10 * x + ch - '0',ch = getchar();
return x;
}
LL a[N][N],b[N][N];
LL solve(int A,int B,int C,int D)
{
if(B > D)swap(A,C),swap(B,D);
if(A > C)
{
int ta = A,tb = B,tc = C,td = D;
A = tc,B = B,C = ta,D = td;
}
LL re = 0;
Rep(k,n)re += (a[C][k] - a[A - 1][k]) * (b[k][D] - b[k][B - 1]);
return re;
}
int main()
{
scanf("%d%d",&n,&m);
Rep(i,n)Rep(j,n)a[i][j] += a[i - 1][j];
Rep(i,n)Rep(j,n)b[i][j] += b[i][j - 1];
while(m --)
{
int A,B,C,D;
printf("%lld\n",solve(A,B,C,D));
}
return 0;
}

1.先考虑功能关系再考虑受力分析，这样不容易忘记动能定理的使用。
2.系统牛顿第二定律的使用。

1.辅助角公式挺重要的。
2.认真带入诱导公式……不然符号会挂。
3.在没有给出两点坐标的时候，坐标记得可交换。
4.正弦定理也很有用。
5.不要乱算截止时间啊！！！

//至于刀剑那个番就不补了……有生之年系列QAQ

## 2017/1/8

bzoj3439: Kpm的MC密码

Description

想Kpm当年为了防止别人随便进入他的MC，给他的PC设了各种奇怪的密码和验证问题（不要问我他是怎么设的。。。），于是乎，他现在理所当然地忘记了密码，只能来解答那些神奇的身份验证问题了。。。


Kpm当年设下的问题是这样的：



Input

第一行一个整数 n 表示字符串的数目



Output

包括n行，第i行包括一个整数，表示所有是si的kpm串的字符串的编号中第ki小的数


vec[x].size()$vec[x].size()$

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
using namespace std;

#define u t[x]
#define o t[y]
#define mid (l + r >> 1)
#define lson u.lc,l,mid,o.lc
#define rson u.rc,mid + 1,r,o.rc
const int N = 300005;
struct Tree{int cnt,lc,rc;}t[N * 26];
int n,m,ch[N][26],id[N],insv,tot = 1,stot,ql,qr,st[N],ed[N],tim,qk,rt[N],oo,Rank[N];
vector<int>vec[N];
#define v ch[x][c]
void ins(char *s,int z)
{
int x = 1,len = strlen(s + 1);
for(int i = len;i;-- i)
{
int c = s[i] - 'a';
if(!v)v = ++ tot;
x = v;
}
id[z] = x;
vec[x].push_back(z);
}
void dfs(int x){Rank[st[x] = ++ tim] = x;for(int c = 0;c < 26;++ c)if(v)dfs(v);ed[x] = tim; }//printf("!dfs %d %d %d\n",x,st[x],ed[x]);}
void ins(int &x,int l,int r,int y)
{
t[x = ++ stot] = o;
u.cnt ++;
if(l == r)return;
if(insv <= mid)ins(lson);
else ins(rson);
}
int Qry(int x,int l,int r,int y)
{
if(l == r)return l;
int z = t[o.lc].cnt - t[u.lc].cnt;
if(z >= qk)return Qry(lson);
else return qk -= z,Qry(rson);
}
void Qry(int S,int T,int i)
{
ql = S - 1,qr = T,qk = i;
if(t[rt[qr]].cnt - t[rt[ql]].cnt < qk)puts("-1");
else printf("%d\n",Qry(rt[ql],1,n,rt[qr]));
}
char s[N];
int main()
{
scanf("%d",&n);
Rep(i,n)scanf("%s",s + 1),ins(s,i);
dfs(1);
rt[0] = ++ stot;
Rep(x,tot)
{
int z = rt[x - 1];
if(vec[Rank[x]].size() != 0)
{
for(vector<int> :: iterator it = vec[Rank[x]].begin();it != vec[Rank[x]].end();++ it)
{
insv = *it;
ins(rt[x],1,n,z);
z = rt[x];
}
}
else rt[x] = rt[x - 1];
}
Rep(i,n){int k;scanf("%d",&k);Qry(st[id[i]],ed[id[i]],k);}
return 0;
}

## 2017/1/9

1.bzoj2849: 和谐串

2.bzoj2400: Spoj 839 Optimal Marks

#include <cstdio>
#include <algorithm>
using namespace std;

#define PR 1010

typedef long long i64;

#define iter(i, n) for (int i = 1; i <= n; ++i)
#define iter0(i, n) for (int i = 0; i < n; ++i)
#define iter_e(i, x) for (int i = pos[x]; i; i = g[i].frt)

struct Edge { int y, frt, f; } g[101000];
int pos[PR], lv[PR], q[PR], w[PR], ex[2010], ey[2010];
int gsz, n, m, S, T;
i64 graph_v, sum_v;

void add_edge(int x, int y, int w0, int w1 = 0) {
g[++gsz] = (Edge) { y, pos[x], w0 }, pos[x] = gsz;
g[++gsz] = (Edge) { x, pos[y], w1 }, pos[y] = gsz;
}

#define v g[i].y
#define fl g[i].f
#define vfl g[i ^ 1].f

const int inf = 1e9;
const int Z = 1000;

bool denote() {
int h, t, x;
iter(i, T) lv[i] = -1;
lv[q[h = t = 1] = S] = 0;
while (h <= t) {
x = q[h++];
iter_e(i, x) if (fl > 0 && lv[v] < 0) lv[q[++t] = v] = lv[x] + 1;
}
return lv[T] > 0;
}

int augment(int x, int f) {
if (x == T) return f;
int ff, s = 0;
iter_e(i, x) if (fl > 0 && f > 0 && lv[v] == lv[x] + 1 && (ff = augment(v, min(f, fl))))
fl -= ff, vfl += ff, f -= ff, s += ff;
if (s == 0) lv[x] = -1;
return s;
}

int max_flow() { int s = 0; for (; denote(); s += augment(S, inf)); return s; }

void build(int d) {
gsz = 1;
iter(i, T) pos[i] = 0;

//S 0
//T 1

iter(i, n) {
if (w[i] >= 0) {
if (w[i] >> d & 1) add_edge(i, T, inf), sum_v += (1 << d);
} else {
}
}

iter(i, m) {
}

int flow = max_flow();

graph_v += (i64) (flow / Z) << d;
sum_v += (i64) (flow % Z) << d;
}

int main() {
scanf("%d%d", &n, &m);
S = n + 1, T = n + 2;
iter(i, n) {
scanf("%d", &w[i]);
}
iter(i, m) scanf("%d%d", &ex[i], &ey[i]);
iter0(i, 31) {
build(i);
}
printf("%lld\n%lld\n", graph_v, sum_v);
return 0;
}

3.bzoj3498: PA2009 Cakes

Claris有一个更厉害的做法，感觉复杂度是差不多的啊。

4.bzoj2705: [SDOI2012]Longge的问题

5.bzoj1411: [ZJOI2009]硬币游戏

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define v edge[i].to
#define RepG(i,x) for(int i = head[x];~ i; i = edge[i].next)
#define fl edge[i].f
#define vfl edge[i ^ 1].f

using namespace std;

typedef long long LL;
const int N = 200005;
LL T;
int a[N],b[N],n,m;
int cal(LL x,LL y)
{
LL L = ((x - y) % m + m) % m;
LL R = (x + y) % m;
if(a[L] == 0)return 0;
if(a[L] == a[R])return 1;
return 2;
}
void doit(LL T,LL len)
{
if(!T)return ;
if((T & 1))
{
for(int i = 0;i < m;++ i)b[i] = cal(i,len);
for(int i = 0;i < m;++ i)a[i] = b[i];
}
doit(T >> 1,len << 1);
}
int main()
{
scanf("%d%lld",&n,&T);
for(int i = 1;i <= n;++ i)scanf("%d",&a[2 * i - 2]);
m = n << 1;
doit(T,1);
for(int i = 0;i < m;++ i)printf("%d%c",a[i],i == m - 1 ? '\n' : ' ');
return 0;
}


## 2017/1/10

1.bzoj 2142: 礼物

n!(na1)!(na1)!(na1a2)!..

n!$n!$是有循环节的，ans[1,n]=rnpk(nmodpk)!modpk$ans[1,n] = r ^{\lfloor \frac {n} {p^k} \rfloor} * (n \mod p ^ k)! \mod p^ k$

p0t$p^0 * t$,p1t$p^1 * t$,…

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
#define mp make_pair
#define X first
#define Y second
vector<pair<int,int> > vec;
int up[200005][105],fac[200005][105],len[105],n,ans[105],m;
typedef long long LL;
LL res[105][2];
LL P,w[105];
void mul(int &x,int y,int z){x = 1ll * x * y % z;}
void init()
{
for(int i = 2;i <= 100000;++ i)
{
if(P % i == 0)
{
int re = 0;
while(P % i == 0)P /= i,re ++;
vec.push_back(mp(i,re));
}
}
int tt = 0;
for(vector<pair<int,int> > :: iterator it = vec.begin();it != vec.end();++ it)
{
int p = (*it).X,z = (*it).Y,re = 1;
Rep(i,z)re *= p;
fac[0][++ tt] = 1;fac[1][tt] = 1;
up[0][tt] = 0,up[1][tt] = 0;len[tt] = re;
for(int i = 2;i <= re;++ i)
{
up[i][tt] = up[i - 1][tt];
fac[i][tt] = fac[i - 1][tt];
int y = i,zz = 0;
while(y % p == 0)zz ++,y /= p;
if(!zz)mul(fac[i][tt],y,re);
up[i][tt] += zz;
}
}
}
int Pw(int x,int y,int p){int re = 1;while(y){if(y & 1)re = 1ll * re * x % p;y >>= 1;x = 1ll * x * x % p;}return re;}
int rev(int x,int y,int z) // x % y意义下的逆元 ,y = z ^ k
{int p = y;y = y / z * (z - 1);return Pw(x,y - 1,p);}
void exgcd(LL a,LL b,LL &x,LL &y){b ? (exgcd(b,a % b,y,x),y -= a / b * x) : (x = 1,y = 0);}
LL CRT(int *r,int *p)
{
LL R,M,k1,k2;
R = r[1],M = p[1];
int zzz = vec.size();
for(int i = 2;i <= zzz;++ i)
{
LL dt = r[i] - R,d = __gcd((LL)p[i],M);
if(dt % d)while(1);
exgcd(M / d,p[i] / d,k1,k2);
k1 = (k1 * dt / d) % (p[i] / d);
R = R + k1 * M;
M = M / d * p[i];
R %= M;
}
return R < 0 ? R + M : R;
}
LL work(int t,int i,int p,int pz)
{
if(t < p)return fac[t][i];
return 1ll * fac[t % pz][i] * Pw(fac[pz - 1][i],t / pz,pz) % pz * work(t / p,i,p,pz) % pz;
}
LL f(int id,int p,int pz){LL re = 1;Rep(i,m)re = re * work(w[i],id,p,pz) % pz;return re;}
LL getP(LL a,int p){LL t = a / p;if(t)t += getP(t,p);return t;}
LL g(int p){LL re = 0;Rep(i,m)re += getP(w[i],p);return re;}
void calc()
{
int i = 0;
for(vector<pair<int,int> > :: iterator it = vec.begin();it != vec.end();++ it)
{
++ i;int p = (*it).X,z = (*it).Y,re = 1,pz = len[i];
res[i][0] = work(n,i,p,pz) % pz;
res[i][0] = 1ll * res[i][0] * rev(f(i,p,pz),pz,p) % pz;
res[i][1] = getP(n,p) - g(p);
int ls = 1;
if(res[i][1] >= z)ls = 0;
else for(int j = 1;j <= res[i][1];++ j)ls = ls * p;
ans[i] = res[i][0] * ls % len[i];
}
}
int main()
{
scanf("%lld%d%d",&P,&n,&m);
LL sss = 0;
Rep(i,m)scanf("%lld",&w[i]),sss += w[i];
if(sss > n)return puts("Impossible"),0;
else w[++ m] = n - sss;
init();
calc();
printf("%lld\n",CRT(ans,len));
return 0;
}

2.Codeforces Round #174 (Div. 1)A

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
typedef long long LL;
const int N = 200005;
LL t[N];
int val[N],n;
void Add(int x,int y){for(;x;x -= x & -x)t[x] += y;}
LL Qry(int x){LL z = 0;for(;x <= 200000;x += x & -x)z += t[x];return z;}
int main()
{
scanf("%d",&n);
int sz = 1;LL sum = 0;
while(n --)
{
int op;
scanf("%d",&op);
if(op == 1)
{
int x,y;
sum += 1ll * x * y;
}
else if(op == 2)
{
int x;
scanf("%d",&x);
val[++ sz] = x;
val[sz] -= Qry(sz);
sum += x;
}
else {sum -= val[sz];val[sz] = 0;sum -= Qry(sz --);}
printf("%.7f\n",1.0 * sum / sz);
}
return 0;
}

3.Codeforces174 B.

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
const int N = 200005;
typedef long long LL;
int to[N][2],val[N],tid[N][2],tim,n;
bool ban[N][2],sur[N][2],g[N][2];
LL tr[N][2];
bool dfs(int x,int d)
{
//  printf("~~ %d %d %d %d\n",x,d,tid[x][d],tim);
if(x > n || x < 1)return 0;
if(sur[x][d])return ban[x][d];
if(tid[x][d] != tim)tid[x][d] = tim;
else return ban[x][d] = 1;
ban[x][d] = dfs(to[x][d],d ^ 1);
sur[x][d] = 1;
return ban[x][d];
}
LL Find(int x,int d)
{
if(x > n || x < 1)return 0;
if(!g[x][d]){g[x][d] = 1;return tr[x][d] = Find(to[x][d],d ^ 1) + val[x];}
else return tr[x][d];
}
int main()
{
scanf("%d",&n);
sur[1][1] = ban[1][1] = 1;
sur[1][0] = 1,ban[1][0] = 0;
Rep(i,n - 1)scanf("%d",&val[i + 1]),to[i + 1][0] = i + 1 - val[i + 1],to[i + 1][1] = i + 1 + val[i + 1];
for(int i = 2;i <= n;++ i)
{

int x = i,d = 0;
++ tim;
if(!sur[x][d])ban[x][d] = dfs(x,d);
if(!g[x][d] && !ban[x][d])tr[x][d] = Find(x,d);
d ^= 1;
++ tim;
if(!sur[x][d])ban[x][d] = dfs(x,d);
if(!g[x][d] && !ban[x][d])Find(x,d);
//printf("Now %d\n",i);
}
Rep(i,n - 1)
{
if(ban[i + 1][0])puts("-1");
else printf("%lld\n",tr[i + 1][0] + i);
}
return 0;
}

4.Codeforces Round #174 (Div. 1)C

5.Codeforces Round #174 (Div. 1)D

## 2017-1-11

1.Codeforces Round #174 (Div. 1)E

ans=ind[i](nd[i]1)

ans=nid[i](nd[i]1)2

Q：你是不是脑残！
A：是的！

2.bzoj4209: 西瓜王

3.Codeforces#385Div1A

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
const int N = 1005;
int n,m,k,fa[N],sz[N],ans[N],f[N];
int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
bool sp[N];
int main()
{
scanf("%d%d%d",&n,&m,&k);
Rep(i,k){int x;scanf("%d",&x);sp[x] = 1;}
Rep(i,n)fa[i] = i,sz[i] = 1;
Rep(i,m)
{
int a,b;
scanf("%d%d",&a,&b);
if(find(a) != find(b))
{
sz[find(b)] += sz[find(a)];
fa[find(a)] = find(b);
}
}
long long an = 0;
//Rep(i,n)ans += 1ll * sz[i] * (sz[i] - 1) / 2;
int re = 0;
Rep(i,n)if(sp[i])re = max(re,sz[find(i)]);
Rep(i,n)
{
if(fa[i] != i)continue;
Rep(j,n)
{
if(sp[j] && find(j) == find(i))
{
f[i] = j;
break;
}
}
}
Rep(i,n)if(sp[i])ans[i] = sz[find(i)];
Rep(i,n)
{
if(fa[i] == i && !f[i])
{
int id = 0,mx = 0;
Rep(j,n)
if(mx < ans[j])mx = ans[j],id = j;
ans[id] += sz[i];
}
}
Rep(i,n)if(ans[i])an += 1ll * ans[i] * (ans[i] - 1) / 2;
an -= m;
printf("%I64d\n",an);
return 0;
}

4.Codeforces#385Div1B

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
const int N = 1005;
int n,mn[N];
void solve(int x,int y)
{
if((1 << x) > n)return ;
int cur = 0;
Rep(i,n)if(((i & (1 << x)) >> x) == y)cur ++;
printf("%d\n",cur);fflush(stdout);
Rep(i,n)if(((i & (1 << x)) >> x) == y)cur --,printf("%d%c",i,cur == 0 ? '\n' : ' '),fflush(stdout);
Rep(i,n){int z;scanf("%d",&z);if(((i & (1 << x)) >> x) != y)mn[i] = min(mn[i],z);}
if(!y)solve(x,y ^ 1);
else solve(x + 1,0);
}
int main()
{
scanf("%d",&n);
Rep(i,n)mn[i] = (int)1e9 + 1;
solve(0,0);
puts("-1");fflush(stdout);
Rep(i,n)printf("%d%c",mn[i],i == n ? '\n' : ' ');
return 0;
}

## 2017-1-12

1.bzoj1977: [BeiJing2010组队]次小生成树 Tree

2.bzoj4710: [Jsoi2011]分特产

-1的那个指数写错了……
3.Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)C

## 2017/1/14

1.bzoj2339:卡农

f[i]$f[i]$表示强制到i$i$是合法的方案数。

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)

using namespace std;
const int N = 1e6 + 5;
int n,m,f[N],fac[N],A[N];
const int mod = 1e8 + 7;
int power(int a,int p,int pc){int tmp = 1;while(p){if(p & 1)tmp = 1ll * a * tmp % pc;p >>= 1;a = 1ll * a * a % pc;}return tmp;}
int main()
{
scanf("%d%d",&n,&m);
fac[0] = 1;
Rep(i,m)fac[i] = 1ll * fac[i - 1] * i % mod;
int all = (power(2,n,mod) - 1 + mod) % mod;
int p = (power(2,n,mod) + mod - 1) % mod;
A[1] = p;A[2] = 1ll * A[1] * (all - 1 + mod) % mod;
for(int i = 3;i <= m;++ i)
{
f[i] = (1ll * A[i - 1] - f[i - 1] - 1ll * f[i - 2] * (i - 1) % mod * (all - (i - 2) + mod) % mod + 2ll * mod) % mod;
A[i] = 1ll * A[i - 1] * (all - i + 1 + mod) % mod;
}
printf("%d\n",1ll * f[m] * power(fac[m],mod - 2,mod) % mod);
return 0;
}

2.4690: Never Wait for Weights

1.a比b轻w。2.询问a比b轻多少。

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)

using namespace std;
const int N = 100005;
int n,fa[N],val[N],m;
char s[5];
int find(int x)
{
int t = fa[x];
if(x != t)fa[x] = find(t);
val[x] = val[t] + val[x];
return fa[x];
}
int Merge(int x,int y,int z)
{
int tx = find(x),ty = find(y);
fa[ty] = tx;
val[ty] = val[x] + z - val[y];
}
int main()
{
while(~scanf("%d%d",&n,&m),n && m)
{
Rep(i,n)fa[i] = i,val[i] = 0;
Rep(i,m)
{
int x,y,z;
scanf("%s%d%d",s,&x,&y);
if(s[0] == '!')
{
scanf("%d",&z);
if(find(x) != find(y))
Merge(x,y,z);
}
else
{
if(find(x) != find(y))
puts("UNKNOWN");
else
{
int tx = find(x),ty = find(y);
printf("%d\n",val[y] - val[x]);
}
}
}
}
return 0;
}

## 2017/1/18

1.[beijing2016]水晶

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define v edge[i].to
#define fl edge[i].f
#define vfl edge[i ^ 1].f
#define mp make_pair
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
using namespace std;
map<pair<int,int>,int >val;
map<pair<int,int>,int >gid;
const int M = 4000005;
const int N = 200005;
const int inf = 1e9;
struct Edge{int next,to,f;}edge[M];
void save(int a,int b,int c)
{
}
bool bfs()
{
Rep(i,T)dep[i] = -1;dep[0] = 0;
int h = 0,t = 0;q[0] = S;
while(h <= t)
{
int x = q[h ++];
RepG(i,x)if(dep[v] == -1 && fl)dep[q[++ t] = v] = dep[x] + 1;
}
return dep[T] > 0;
}
int dfs(int x,int f)
{
if(x == T)return f;
int s = 0,ff;
RepG(i,x)if(dep[v] == dep[x] + 1 && f && fl && (ff = dfs(v,min(f,fl))))
s += ff,fl -= ff,vfl += ff,f -= ff;
if(!s)dep[x] = -1;
return s;
}
int mxf(){int s = 0;for(;bfs();s += dfs(S,inf));return s;}
int tot;
int main()
{
scanf("%d",&n);
Rep(i,n)
{
int x,y,z,c;
scanf("%d%d%d%d",&x,&y,&z,&c);
x -= z,y -= z; // [3000,3000];
if((x + y) % 3 == 0)
{
c *= 11;
val[make_pair(x,y)] += c;tot += c;
}
else
{
c *= 10;
val[make_pair(x,y)] += c;tot += c;
}
}
int zz = 0;
for(map<pair<int,int>,int > :: iterator it = val.begin();it != val.end();++ it)
{
pair<int,int> idx = it -> first;
int c = it -> second;
++ zz;gid[idx] = zz,va[zz] = c,cor[zz][0] = idx.first,cor[zz][1] = idx.second;
}
T = 2 * zz + 1;
Rep(i,zz)
{
int x = cor[i][0],y = cor[i][1];
int _x,_y,z;
if(((x + y) % 3 + 3) % 3 == 0)
{
save(i,i + zz,va[i]);

_x = x - 1,_y = y - 1;
z = gid[mp(_x,_y)];
if(z)save(z,i,inf);

_x = x,_y = y + 1;
z = gid[mp(_x,_y)];
if(z)save(z,i,inf);

_x = x + 1,_y = y;
z = gid[mp(_x,_y)];
if(z)save(z,i,inf);

_x = x + 1,_y = y + 1;
z = gid[mp(_x,_y)];
if(z)save(i + zz,z,inf);

_x = x - 1,_y = y;
z = gid[mp(_x,_y)];
if(z)save(i + zz,z,inf);

_x = x,_y = y - 1;
z = gid[mp(_x,_y)];
if(z)save(i + zz,z,inf);
}
else if(((x + y) % 3 + 3) % 3 == 1) // S侧
save(S,i,va[i]);
else save(i,T,va[i]);// T侧
}
printf("%.1f\n",(tot - mxf()) / 10.0);
return 0;
}

2017/1/20
1.两个串：

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define R0(i,n) for(int i = 0;i < n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
using namespace std;
const int N = 400005;
struct Virt
{
double r,i;
Virt(double R = 0.0,double I = 0.0){this -> r = R,this -> i = I;}
Virt operator + (const Virt &x){return (Virt){x.r + r,x.i + i};}
Virt operator - (const Virt &x){return (Virt){r - x.r,i - x.i};}
Virt operator * (const Virt &x){return (Virt){r * x.r - i * x.i,x.r * i + r * x.i};}
};
const double PI = acos(-1);
int n,m,LEN,Rev[N],ans1[N],ans2[N],ans3[N];
{
int LG = 0;
for(LEN = 1;LEN <= 2 * n;LEN <<= 1,LG ++);
R0(i,LEN)Rev[i] = Rev[i >> 1] >> 1 | ((i & 1) << (LG - 1));
}
void FFT(Virt *F,int ty = 1)
{
R0(i,LEN)if(i < Rev[i])swap(F[i],F[Rev[i]]);
for(int i = 1;i < LEN;i <<= 1)
{
Virt wn(cos(PI / i),sin(PI / i) * ty);
for(int j = 0;j < LEN;j += (i << 1))
{
Virt w(1,0);
for(int k = 0;k < i;++ k,w = w * wn)
{
Virt u = F[j + k],v = w * F[j + k + i];
F[j + k] = u + v,F[j + k + i] = u - v;
}
}
}
if(ty == -1)R0(i,LEN)F[i].r /= LEN;
}
Virt A[N],B[N],C[N],C1[N],C2[N],C3[N];
char s[N],s2[N];
int a[N],b[N],a2[N],b2[N];
bool f[N];
int main()
{
scanf("%s",s);n = strlen(s);
R0(i,n)a[i] = s[i] - 'a' + 1,a2[i] = a[i] * a[i];
scanf("%s",s2);m = strlen(s2);
R0(i,m){b[i] = (s2[m - i - 1] == '?' ? 0 : (s2[m - i - 1] - 'a' + 1));b2[i] = b[i] * b[i];}

R0(i,LEN)A[i].r = A[i].i = B[i].r = B[i].i = 0;
R0(i,n)A[i].r = a2[i],A[i].i = 0;
R0(i,m)B[i].r = b[i],B[i].i = 0;
FFT(A),FFT(B);
R0(i,LEN)C1[i] = A[i] * B[i];
FFT(C1,-1);

R0(i,LEN)A[i].r = A[i].i = B[i].r = B[i].i = 0;
R0(i,n)A[i].r = a[i],A[i].i = 0;
R0(i,m)B[i].r = b2[i],B[i].i = 0;
FFT(A),FFT(B);
R0(i,LEN)C2[i] = A[i] * B[i];
FFT(C2,-1);

R0(i,LEN)A[i].r = A[i].i = B[i].r = B[i].i = 0;
R0(i,n)A[i].r = 1,A[i].i = 0;
R0(i,m)B[i].r = b[i] * b2[i],B[i].i = 0;
FFT(A),FFT(B);
R0(i,LEN)C3[i] = A[i] * B[i],C2[i].r *= 2.0;
FFT(C3,-1);

R0(i,n)ans1[i] = (int)(C1[i].r + 0.5);
R0(i,n)ans2[i] = (int)(C2[i].r + 0.5);
R0(i,n)ans3[i] = (int)(C3[i].r + 0.5);

//R0(i,n)C[i] = C1[i] - C2[i] + C3[i];
int cur = 0;

for(int i = m - 1;i < n;++ i)if(ans1[i] - ans2[i] + ans3[i] == 0)cur ++;
printf("%d\n",cur);
for(int i = m - 1;i < n;++ i)if(ans1[i] - ans2[i] + ans3[i] == 0)printf("%d\n",i - m + 1);
return 0;
}

## 2017/1/21

1.4078: [Wf2014]Metal Processing Plant

2.3622: 已经没有什么好害怕的了

f[i][j]$f[i][j]$表示到了第i$i$个，前面比a[i]$a[i]$小的还至少j$j$个没被匹配的方案数。
f[i][j]=f[i1][j]+f[i1][j1](lenj+1);$f[i][j] = f[i - 1][j] + f[i - 1][j - 1] * (len - j + 1);$

Q：为什么那个转移是至少
A：想一想就知道辣……

ans=i>=k(ik)(1)ikg[i]$ans = \sum_{i >= k}\binom {i}{k} (-1)^{i - k}g[i]$

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
using namespace std;
const int N = 2005;
const int mod = 1e9 + 9;
int fac[N],n,k,f[N][N],a[N],b[N],g[N],h[N],rev[N];
void Add(int &x,int y){(x += y) %= mod;}
int pw(int x,int y){int re = 1;while(y){if(y & 1)re = 1ll * x * re % mod;y >>= 1;x = 1ll * x * x % mod;}return re;}
int calc(int j,int i,int val)
{
int re = 0,z = i - j;
re = 1ll * val * fac[i] % mod * rev[i - j] % mod * rev[j] % mod;
if(z & 1)return (mod - re) % mod;
else return re;
}
int main()
{
scanf("%d%d",&n,&k);
Rep(i,n)scanf("%d",&a[i]);
Rep(i,n)scanf("%d",&b[i]);
sort(a + 1,a + 1 + n);
sort(b + 1,b + 1 + n);
f[0][0] = 1;
int m = 0;

for (int i = 1; i <= n; ++i)
{
while (m < n && b[m + 1] < a[i]) ++ m;

for (int j = 0; j <= m; ++j)
{
if (j > 0) Add(f[i][j],1ll * f[i - 1][j - 1] * (m - j + 1) % mod);
}
}
fac[0] = 1,rev[0] = 1;
for(int i = 1;i <= n;++ i)fac[i] = 1ll * fac[i - 1] * i % mod,rev[i] = pw(fac[i],mod - 2);

for(int i = 0;i <= n;++ i)g[i] = 1ll * f[n][i] * fac[n - i] % mod;//,printf("now %d %d\n",i,g[i]);
if((n - k) % 2)return puts("0"),0;
k = (n - k) / 2; // k个
k = n - k;
int ans = 0;
for(int i = k;i <= n;++ i)Add(ans,calc(k,i,g[i]));
printf("%d\n",ans);
return 0;
}

3.4245: [ONTAK2015]OR-XOR

#include<bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;i ++)
using namespace std;
int m,n;
long long a[500001],ans;
bool del[500001];
int main ()
{
scanf("%d%d",&n,&m);
Rep(i,n)scanf("%lld",&a[i]),a[i] ^= a[i - 1];
for(int bit = 62;~ bit; -- bit)
{
int cur = 0;
Rep(i,n)
if(!del[i] && !((1ll << bit) & a[i]))cur ++;
if(cur < m || (a[n] & (1ll << bit)))ans |= 1ll << bit;
else Rep(i,n)if(!del[i] && ((1ll << bit) & a[i]))del[i] = 1;
}
printf("%lld\n",ans);
return 0;
}
﻿

2017/1/22
1.1095: [ZJOI2007]Hide 捉迷藏

#include <bits/stdc++.h>
#define v edge[i].to
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define RepG(i,x) for(int i = head[x];~ i;i = edge[i].next)
using namespace std;
const int N = 100005;

int node_cnt,rt,tb[N],sz[N],head[N],cnt,black,c[N],tim,tid[N],rmq[N * 2][18],lg[N * 2],fa[N],dep[N],n,m;
bool done[N];
struct Edge{int next,to;}edge[N << 1];
struct Heap
{
priority_queue<int>h,d;
void ins(int val){ h.push(val); }
void del(int val){ d.push(val); }
void fi() { while(!d.empty() && h.top() == d.top()) h.pop(), d.pop(); }
void pop(){ fi(); h.pop(); }
int fir(){ fi(); return h.top();}
int sec(){ fi(); int x,y; x = fir(); pop(); y = fir(); ins(x);return y;}
int total(){ return h.size() - d.size();}
void change(int x,int ty) { if(ty)ins(x); else del(x); }
}h1[N],h2[N],ans;
void add_ans(Heap &s){if(s.total() >= 2)ans.ins(s.fir() + s.sec());}
void del_ans(Heap &s){if(s.total() >= 2)ans.del(s.fir() + s.sec());}
void get(int x,int f)
{
sz[x] = 1;tb[x] = 0;
RepG(i,x)
{
if(done[v] || v == f)continue;
get(v,x);
sz[x] += sz[v];
tb[x] = max(tb[x],sz[v]);
}
tb[x] = max(node_cnt - sz[x],tb[x]);
if(tb[x] < tb[rt])rt = x;
}
void dfs(int x,int f,int dep,Heap &s){s.ins(dep);RepG(i,x)if(!done[v] && v != f)dfs(v,x,dep + 1,s);}
void solve(int x,int s,int org = 0)
{
tb[0] = 1000000;node_cnt = s;
//dfs(x,0,1,h1[x]);
rt = 0;get(x,0);
dfs(x,0,1,h1[rt]);
x = rt;done[x] = 1;
h2[x].ins(0);
//printf("PUSH %d %d\n",x,0);
//dfs(x,0,1,h1[x]);
if(org)
{
fa[x] = org;
h2[org].ins(h1[x].fir());
//  printf("PUSH %d %d\n",org,h1[x].fir());
}
get(x,0);
RepG(i,x)if(!done[v])solve(v,sz[v],x);
}
void rmq_dfs(int x,int fa)
{
rmq[++ tim][0] = dep[x] = (dep[fa] + 1);tid[x] = tim;  // tid表示x的第一次出现位置
RepG(i,x)if(v != fa)rmq_dfs(v,x),rmq[++ tim][0] = dep[x];
}
void rmq_build(int s)
{
for(int i = 2;i <= s;++ i)lg[i] = lg[i >> 1] + 1;
for(int j = 1;j <= lg[s];++ j)
for(int i = 1;i <= (s + 1 - (1 << j) );++ i)
rmq[i][j] = min(rmq[i][j - 1],rmq[i + (1 << (j - 1))][j - 1]);
}
int rmq_dep(int a,int b) // return dep[lca(a,b)];
{
a = tid[a],b = tid[b];
if(a > b)swap(a,b);
int s = lg[b - a + 1];
return min(rmq[a][s],rmq[b - (1 << s) + 1][s]);
}
int dis(int a,int b){return dep[a] + dep[b] - 2 * rmq_dep(a,b);}
void Modify(int x,int col)
{
int y = x;
while(fa[x])
{
del_ans(h2[fa[x]]);
if(h1[x].total())h2[fa[x]].del(h1[x].fir());
h1[x].change(dis(fa[x],y),col);
if(h1[x].total())h2[fa[x]].ins(h1[x].fir());
x = fa[x];
}
}
int main()
{
//freopen("data.in","r",stdin);
//freopen("1095.out","w",stdout);
scanf("%d",&n);
Rep(i,n - 1){int a,b;scanf("%d%d",&a,&b);save(a,b),save(b,a);}
solve(1,n);rmq_dfs(1,0);rmq_build(tim);
//Rep(i,n)printf("%d %d\n",i,fa[i]);
scanf("%d",&m);
black = n;
while(m --)
{
char op[5];
scanf("%s",op);
if(op[0] == 'C')
{
int x;scanf("%d",&x);
Modify(x,c[x]);
c[x] ? ++ black : -- black;
c[x] ^= 1;
}
else
{
if(black < 2)printf("%d\n",black - 1);
else printf("%d\n",ans.fir());
}
}
return 0;
}

2.Codeforces Round #257 (Div. 1)D. Jzzhu and Numbers
orz fsf系列。

2017/1/25

1.2301: [HAOI2011]Problem b

2.2820: YY的GCD

3.4407: 于神之怒加强版

4.2154: Crash的数字表格

5.2693: jzptab

6.wyx：

7.3529: [Sdoi2014]数表

8.3994: [SDOI2015]约数个数和

d|(i,j)<=>d|i,d|j

ij[(i,j)=1]=d=1NNdMdμ(d)

nimjij=(n+1)n(m+1)m/4$\sum_{i}^{n}\sum_{j}^{m} ij = (n+1)*n*(m+1)*m/4$
[xsfn]<=>[μ(x)2=1]$[x \in sfn] <=> [\mu(x)^2 = 1]$

WC铁牌滚粗。

A题直接暴力就行了，看起来就很靠谱。
B题的话，题意是让你找出N+1个点的集合划分 - N个点的集合划分。

Bi+1=jBj(ij)$B_{i+1} = \sum_jB_j\binom i j$

C题是个2SAT，还没有写。DE没有看。

Bzoj 3601 一个人的数论。

i=1n[(i,n)=1]ie

i=1nd|n,d|iμ(d)ie

d|nμ(d)dei=1ndie

f(n)=μ(n)ne

g(n)=i=1nie

d|nf(d)g(nd)

g(n)=i=0e+1aini

d|nf(d)i=0e+1ai(nd)i

i=0e+1aid|nf(d)(nd)i

hi(n)=d|nf(d)(nd)i$h_i(n) = \sum_{d|n}f(d)(\frac{n}{d})^i$

i=0e+1aihi(n)

n$n$实在很大，那么只能考虑一个pk$p^k$.
hi(pk)=j=0kμ(pj)pjepi(kj)

mu(pk)?$mu(p^k)?$
hi(pk)=(pk)i(pk1)ipe=pki(1pei).

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define Dwn(i,n) for(int i = n;i ;i --)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
using namespace std;
const int N = 115;
const int M = 1105;
int e,w,b[N],a[N][N],X[N],p[M],q[M];
const int mod = (int)1e9 + 7;
int pw(int x,long long y,int m)
{
int re = 1;
if(y < 0)return pw(pw(x,m - 2,m),-y,m);
while(y)
{
if(y & 1)re = 1ll * x * re % mod;
y >>= 1; x = 1ll * x * x % mod;
}
return re;
}
void print()
{
rep(i,0,e)
{
rep(j,0,e)cout << a[i][j] << ' ';
cout << b[i];
cout << endl;
}
}
void Gauss()
{
int j,k;
++ e;
rep(i,0,e)
{
for(j = i;j <= e;++ j) if(a[j][i]){j = i;break;}
if(i != j){for(k = 0;k <= e;++ k)swap(a[i][k],a[j][k]);swap(b[i],b[j]);}
int r = pw(a[i][i],mod - 2,mod);
for(j = i + 1;j <= e;++ j)
{
if(!a[j][i])continue;
int z = 1ll * a[j][i] * r % mod;
for(k = i;k <= e;++ k)a[j][k] = (a[j][k] - 1ll * a[i][k] * z % mod + mod) % mod;
b[j] = (b[j] - 1ll * b[i] * z % mod + mod) % mod;
}
}
dwn(i,e,0)
{
X[i] = b[i];
for(j = i + 1;j <= e;++ j)X[i] = (X[i] - 1ll * X[j] * a[i][j] % mod + mod) % mod;
X[i] = 1ll * X[i] * pw(a[i][i],mod - 2,mod) % mod;
}
-- e;
//rep(i,0,e + 1)printf("!!%d ",X[i]);
}
void init()
{
for(int i = 0;i <= e + 1;++ i)
{
int ie = pw(i + 1,e,mod);
for(int j = 0;j <= e + 1;++ j)a[i][j] = pw(i + 1,j,mod);
if(i)b[i] = (b[i - 1] + ie) % mod;
else b[i] = ie;
}
}
int solve(int P,int Q,int i){return 1ll * pw(P,1ll * Q * i,mod) * ( (1ll - pw(P,e - i,mod) + mod) % mod ) % mod;}
int main()
{
scanf("%d%d",&e,&w);
init();
Gauss();
rep(i,1,w)scanf("%d%d",&p[i],&q[i]);
int ans = 0;
rep(i,0,e + 1)
{
int re = X[i];
rep(j,1,w)re = (1ll * re * solve(p[j],q[j],i)) % mod;
ans = (ans + re) % mod;
}
printf("%d\n",ans);
return 0;
}

CodeforcesRound213Div1翻译和题解和程序暂未上传T.T
2/14：但是已经算是完成了ABD，晚上回去把CDE写完。
2/14：情人节，打开http://codeforces.com/contest/446，去参节FFF团！
2/14有一场Codeforces，参加并掉rating！

# 2017/2/15

fsf出的模拟赛= =。

A题发现读错题了= =。不过也是前缀和瞎扫一扫就完了。
B题的话xjb用map搞搞……

#include <bits/stdc++.h>
#define Rep(i,n) for(int i = 1;i <= n;++ i)
#define rep(i,a,b) for(int i = a;i <= b;++ i)
#define dwn(i,a,b) for(int i = a;i >= b;-- i)
#define Dwn(i,n) for(int i = n;i;-- i)
using namespace std;
const int N = 200005;
map<int,int>a,b;
vector<int>vec;
int val[N],n,m,p,q[N];
void solve(int x)
{
int h = 0,t = 0;
b.clear();
for(int i = x;i <= n;i += p)
{
q[++ t] = val[i];b[val[i]] ++;
if(t - h == m)
{
if(a == b)vec.push_back(h * p + x);
int y = q[++ h];
b[y] --;if(!b[y])b.erase(y);
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
Rep(i,n)scanf("%d",&val[i]);
Rep(i,m){int x;scanf("%d",&x);a[x] ++;}
Rep(i,p)solve(i);
sort(vec.begin(),vec.end());
printf("%d\n",vec.size());
for(int i = 0;i < vec.size();++ i)printf("%d ",vec[i]);
return 0;
}

CD好像已经快忘记了= =

E

f[i][l][r]$f[i][l][r]$表示到了第i个数值，已经打开了l$l$个左括号，打开了r$r$个右括号的合法的方案数。

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120