联赛刷水计划

CNT = 9

太弱了只会跟着别人的list刷水题T_T

【bzoj2818】

sb欧拉函数题

gcd(x,y)==p <=> gcd(x/p,y/p)==1

然后就是枚举素数算一算phi(n/p)

#include <bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;i++)

typedef long long ll;

ll phi[10000001];
int pri[1000001], vis[10000001];
int n , tot;

inline void calc_phi() {
    For(i , 2 , n) {
        if (!vis[i]) pri[++ tot] = i , phi[i] = i - 1;
        For(j , 1 , tot) if ((ll) pri[j] * i > n) break;
        else {
            int t = i * pri[j];
            vis[t] = 1;
            if (i % pri[j] == 0) { phi[t] = phi[i] * pri[j] ; break ; }
            else phi[t] = phi[i] * (pri[j] - 1);
        }
    }
}

int main() {
    scanf("%d" , &n);
    calc_phi();
    For(i , 2 , n) phi[i] += phi[i - 1];
    ll ans = 0;
    For(i , 1 , tot) ans += 2 * phi[n / pri[i]] + 1;
    printf("%lld\n" , ans);
    return 0;
}

【bzoj2190】

还是sb欧拉函数题

写的时候忘记边界phi[1]=1了调了好久……弱的不行

显然一个点(x,y)能被看到当且仅当gcd(x,y)==1

也就是说题目要统计 1<=i,j<=n1[gcd(i,j)==1]

欧拉函数像上一题那样随便搞搞就行了

#include <bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;i++)

typedef long long ll;

int vis[65535] , pri[8191] , phi[65535] , n , tot;

void init() {
    phi[1] = 1;
    For(i , 2 , n) {
        if (!vis[i]) pri[++ tot] = i , phi[i] = i - 1;
        for(int j = 1 ; j <= tot && pri[j] * i <= n ; j ++) {
            int t = pri[j] * i;
            vis[t] = 1;
            if (i % pri[j] == 0) { phi[t] = phi[i] * pri[j] ; break ; }
            else phi[t] = phi[i] * (pri[j] - 1);
        }
    }
}

int main() {
    scanf("%d" , &n);
    init();
    ll ans = 1;
    For(i , 1 , n - 1) ans += (ll) 2 * phi[i];
    printf("%lld\n" , ans);
    return 0;
}

【bzoj1257】

小学奥数经常会碰到的奇怪的东西!
1<=j<=nk mod j=1<=j<=n(kkjj)
注意到 kj 这个东西取值大部分是一样的所以直接枚举这个东西然后乱搞统计。

#include <bits/stdc++.h>

typedef long long ll;

int n , k;

int main() {
    scanf("%d%d" , &n , &k);
    ll ans = (ll)n * k;
    if (n > k) n = k;
    for(int i = 1 , j , l , r;i <= n;i = r + 1) {
        j = k / i;
        l = k / (j + 1) + 1 , r = std::min(k / j , n);
        ans -= (ll) (l + r) * (r - l + 1) / 2 * j;
    }
    printf("%lld\n" , ans);
    return 0;
}

【bzoj2761】
看到有人这题PE了就随手写了一发
然后也PE了T_T
注意输出格式!!!!!
每一行不能有多余空格回车等字符!!!
第一个数输出前无空格,后面每一个输出的数前面加一个空格
然后也是水题……
交了三次T_T

#include <bits/stdc++.h>
using namespace std;
#define For(i,a,b) for(int i=a;i<b;i++)
#define maxn 65535

inline int rd() {
    char c = getchar();
    while (!isdigit(c) && c != '-') c = getchar() ; int x = 0 , f = 1;
    if (c == '-') f = -1; else x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x * f;
}

int a[maxn] , b[maxn] , c[maxn];
int n;
map<int , int> s;

void input() {
    s.clear();
    n = rd();
    For(i , 0 , n) if (s.find(a[i] = rd()) == s.end()) s[a[i]] = i;
    For(i , 0 , n) c[i] = 0;
}

void solve() {
    for(map<int , int>::iterator it = s.begin() ; it != s.end() ; it ++) b[it -> second] = it -> first , c[it -> second] = 1;
    printf("%d" , b[0]);
    For(i , 1 , n) if (c[i]) printf(" %d" , b[i]);
}

int main() {
    int T = rd();
    while (T --) {
        input();
        solve();
        if (T) puts("\0");
    }
    return 0;
}

【bzoj3209】
弱得不行,调了1h+ T_T
1<=k<=nbitscount(k)
注意到二进制位的个数只有那么多个,于是枚举二进制位1的个数,然后用类似数位DP的东西乱搞统计。
比如说现在要t个1,枚举到了(从右往左)第i位,现在的贡献就是 (i1t) ,所以就一路加起来。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)

typedef long long ll;

const int mod = 10000007;

int a[65] , l , s[65];
ll n , c[65][65];

ll Pow(ll a , ll b) {
    ll ret = 1;
    while (b) {
        if (b & 1) ret = ret * a % mod;
        a = a * a % mod , b >>= 1;
    }
    return ret;
}

void init() {
    for(ll  t = n + 1;t;t >>= 1) a[++ l] = (t & 1);
    c[0][0] = 1;
    rep(i , 1 , l + 1) {
        c[i][0] = 1;
        rep(j , 1 , i) c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
    }
}

inline ll calc(int t) {
    ll ret = 0;
    per(i , l , 1) if (a[i]) {
        ret += c[i - 1][t --];
        if (t < 0) break;
    }
    return ret;
}

void solve() {
    ll ans = 1;
    rep(i , 1 , l) ans = ans * Pow(i , calc(i)) % mod;
    printf("%lld\n" , ans);
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.txt" , "r" , stdin);
        freopen("data.out" , "w" , stdout);
    #endif
    scanf("%lld" , &n);
    init();
    solve();
    return 0;
}

【bzoj1468】
点分经典裸题(刷题量T_T)
10min写完蛤蛤蛤蛤

#include <bits/stdc++.h>
using namespace std;
#define For(i,a,b) for(int i=a;i<b;i++)
#define fore(i,u) for(int i=head[u];i;i=nxt[i])
#define maxn 100007

inline int rd() {
    char c = getchar();
    while (!isdigit(c)) c = getchar() ; int x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x;
}

typedef int arr[maxn];

arr to , val , nxt , head , fa , vis , dis , sz , mx;
int n , ett , K , mn , rt , ans , tot;

inline void ins(int w , int u , int v) {
    to[++ ett] = v , val[ett] = w , nxt[ett] = head[u] , head[u] = ett;
    to[++ ett] = u , val[ett] = w , nxt[ett] = head[v] , head[v] = ett;
}

inline void upmax(int&a , int b) { if (a < b) a = b ; }

void input() {
     n = rd();
     For(i , 1 , n) ins(rd() , rd() , rd());
     K = rd();
}

#define ok (v != fa && !vis[v])

void dfs_size(int u , int fa) {
    sz[u] = 1;
    fore(i , u) {
        int v = to[i];
        if (!ok) continue;
        dfs_size(v , u);
        sz[u] += sz[v] , upmax(mx[u] , sz[v]);
    }
}

void dfs_root(int r , int u , int fa) {
    upmax(mx[u] , sz[r] - sz[u]);
    if (mx[u] < mn) rt = r , mn = mx[u];
    fore(i , u) {
        int v = to[i];
        if (!ok) continue;
        dfs_root(r , v , u);
    }
}

void dfs_dis(int u , int fa , int w) {
    dis[tot ++] = w;
    fore(i , u) {
        int v = to[i];
        if (!ok) continue;
        dfs_dis(v , u , w + val[i]);
    }
}

int calc(int u , int d) {
    int ret = 0; tot = 0;
    dfs_dis(u , 0 , d);
    sort(dis , dis + tot);
    for(int i = 0 , j = tot - 1 ; i < j ; i ++) {
        while (dis[i] + dis[j] > K && i < j) j --;
        ret += j - i;
    }
    return ret;
}

void dfs(int u) {
    mn = n;
    dfs_size(u , 0);
    dfs_root(u , u , 0);
    vis[rt] = 1 , ans += calc(rt , 0);
    fore(i , rt) {
        int v = to[i];
        if (vis[v]) continue;
        ans -= calc(v , val[i]);
        dfs(v);
    }
}

void solve() {
    dfs(1);
    printf("%d\n" , ans);
}

int main() {
    input();
    solve();
    return 0;
}

【bzoj3207】
孟爷的题,题意大坑。。
给一个序列,有m次询问,每次询问一个长度为K的序列是否在某个区间内出现过。
子串不是子序列!
差不多就是GSS系列,只不过问的是长度为K的串。既然是串哈希一下就OK,偷懒用了 O(nk) 的哈希似乎也没有问题……
数据范围有点大,就可持久化咯。
一开始哈希是unsigned就想搞可持久化trie……不过其实把哈希值离散化一下就可以了。

#include <bits/stdc++.h>
using namespace std;
#define For(i,a,b) for(int i=a;i<=b;i++)
#define maxm 2097151
#define maxn 131071
#define P 107

typedef long long ll;
typedef unsigned long long ull;
typedef map<ull , int>::iterator iter;
typedef int seg[maxm];
typedef int arr[maxn];

map<ull , int> ord;

arr a , rt;
seg lc , rc , sz;

int n , m , K , tot;
ull h[maxn];

inline int rd() {
    char c = getchar();
    while (!isdigit(c) && c != '-') c = getchar() ; int x = 0 , f = 1;
    if (c == '-') f = -1 ; else x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x * f;
}

inline ull Hash(int*a) {
    ull ret = 0;
    For(i , 0 , K - 1) {
        ret *= P;
        ret += a[i];
    }
    return ret;
}

void update(int pr , int&nr , int l , int r , int v) {
    sz[nr = ++ tot] = sz[pr] + 1;
    if (l == r) return;
    int m = (l + r) >> 1;
    lc[nr] = lc[pr] , rc[nr] = rc[pr];
    if (v < m) update(lc[pr] , lc[nr] , l , m , v);
    else update(rc[pr] , rc[nr] , m + 1 , r , v);
}

int  query(int pr , int nr , int l , int r , int v) {
    if (l == r) return sz[nr] - sz[pr];
    int m = (l + r) >> 1;
    if (v < m) return query(lc[pr] , lc[nr] , l , m , v);
    else return query(rc[pr] , rc[nr] , m + 1 , r , v);
}

void input() {
    n = rd() , m = rd() , K = rd();
    For(i , 1 , n) a[i] = rd();
    For(i , 1 , n - K + 1) {
        h[i] = Hash(a + i);
        ord[h[i]] = i;
    }
    ull t = 0;
    for(iter it = ord.begin();it != ord.end();it ++)
        it -> second = t ++;
    For(i , 1 , n) {
        t = ord[h[i]];
        update(rt[i - 1] , rt[i] , 0 , n , t);
    }
}

void solve() {
    while (m --) {
        int l = rd() , r = rd();
        For(i , 1 , K) a[i] = rd();
        ull t = Hash(a + 1);
        if (ord.find(t) == ord.end()) {
            puts("Yes");
            continue;
        }
        int k = ord[t];
        int ans = query(rt[l - 1] , rt[r] , 0 , n , k);
        puts(ans ? "No" : "Yes");
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.txt" , "r" , stdin);
    #endif
    input();
    solve();
    return 0;
}

【bzoj3208】
还是孟爷的题,不过是良心大水题√
经典DP的“动态版”,然而动态并没有什么卵用,闷声大暴力就可以了2333

#include <bits/stdc++.h>
#define For(i,a,b) for(int i=a;i<=b;i++)

const int fx[] = {0 , 0 , 1 , -1};
const int fy[] = {1 , -1 , 0 , 0};

typedef int mat[707][707];

mat h , s , f;
int n , m;

void input() {
    scanf("%d" , &n);
    For(i , 1 , n) For(j , 1 , n) scanf("%d" , &h[i][j]);
    scanf("%d" , &m);
    For(i , 1 , n) s[i][0] = s[i][n + 1] = s[n + 1][i] = s[0][i] = 1;
}

inline void upmax(int&a , int b) { if (a < b) a = b ; }

inline void cover(int a , int b , int c , int d , int v) {
    For(i , a , c) For(j , b , d) s[i][j] = v;
}

int dp(int x , int y) {
    if (f[x][y] != -1) return f[x][y];
    int ret = 0;
    For(i , 0 , 3) {
        int nx = x + fx[i] , ny = y + fy[i];
        if (s[nx][ny]) continue;
        if (h[nx][ny] >= h[x][y]) continue;
        upmax(ret , dp(nx , ny));
    }
    return f[x][y] = ret + 1;
}

inline void query() {
    int ans = 0;
    For(i , 1 , n) For(j , 1 , n) f[i][j] = -1;
    For(i , 1 , n) For(j , 1 , n) if (f[i][j] == -1 && !s[i][j]) dp(i , j);
    For(i , 1 , n) For(j , 1 , n) upmax(ans , f[i][j]);
    printf("%d\n" , ans) ;
}

void solve() {
    while (m --) {
        char cmd[10];
        int a , b , c , d;
        scanf("%s" , cmd);
        if (cmd[0] == 'Q') {
            query();
            continue;
        }
        scanf("%d%d%d" , &a , &b , &c);
        if (cmd[0] == 'C') {
            h[a][b] = c;
            continue;
        }
        scanf("%d" , &d);
        cover(a , b , c , d , cmd[0] == 'S');
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.txt" , "r" , stdin);
    #endif
    input();
    solve();
    return 0;
}

【bzoj1083】
生成树超级大水题
然而看错数据范围狂WA 7发QAQ

#include <bits/stdc++.h>
using namespace std;
#define For(i,a,b) for(int i=a;i<b;i++)
#define Dwn(i,a,b) for(int i=a-1;i>=b;i--)
#define maxn 100001

inline int rd() {
    char c = getchar();
    while (!isdigit(c)) c = getchar() ; int x = c - '0';
    while (isdigit(c = getchar())) x = x * 10 + c - '0';
    return x;
}

struct node {
    int u , v , c;
    node(int u = 0 , int v = 0 , int c = 0):u(u) , v(v) , c(c) { }
}e[maxn];

int n , m , tot , fa[maxn];

bool cmp(const node a , const node b)
    { return a.c < b.c; }

void input() {
    n = rd() , m = rd();
    For(i , 0 , m) e[i].u = rd() , e[i].v = rd() , e[i].c = rd();
    sort(e , e + m , cmp);
}

int find(int u)
    { return u == fa[u] ? u : fa[u] = find(fa[u]) ; }

bool ok(int x) {
    tot = 1;
    For(i , 1 , n + 1) fa[i] = i;
    fa[find(e[x].u)] = find(e[x].v);
    Dwn(i , x , 0) {
        int u = find(e[i].u) , v = find(e[i].v);
        if (u == v) continue;
        fa[u] = v , tot ++;
    }
    return tot == n - 1;
}

void solve() {
    For(i , 0 , m) if (ok(i))
        { printf("%d %d\n" , n - 1 , e[i].c) ; return ; }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("data.txt" , "r" , stdin);
    #endif
    input();
    solve();
    return 0;
}

你可能感兴趣的:(gcd,phi)