六省联考2017

期末考试

sol

因为时间范围很小,所以可以利用单调性求出对于每一个时间$t$,当最晚的成绩公布时间为$t$时学生产生的不满意度总和$f_t$和让所有课程的公布时间不大于$t$的前提下课程产生的最小不满意度$g_t$.复杂度$O(nlogn)$,瓶颈是排序.

但是上面那个做法太不优雅了.我们可以发现$g_t$和$f_t$差分之后的数组都是单调不减,也就是$f_t+g_t$差分之后单调不减,也就意味着$f_t+g_t$这个数列是单谷数列.我们在时间范围上三分数列极小值即可.

然后因为三分太慢获得了LOJ倒数

#include<bits/stdc++.h>
using namespace std;

int read(){
    int a = 0; char c = getchar(); bool f = 0;
    while(!isdigit(c)){f = c == '-'; c = getchar();}
    while(isdigit(c)){
        a = a * 10 + c - 48; c = getchar();
    }
    return f ? -a : a;
}

#define int long long
const int _ = 1e5 + 7; int A , B , C , N , M , T[_] , P[_];
int max(int a , int b){return a > b ? a : b;}

int calc(int x){
    int sum = 0 , cntl = 0 , cntr = 0;
    for(int i = 1 ; i <= N ; ++i) sum += max(x - T[i] , 0) * C;
    for(int i = 1 ; i <= M ; ++i) P[i] <= x ? cntl += x - P[i] : cntr += P[i] - x;
    return A > B ? sum + cntr * B : sum + min(cntl , cntr) * A + max(cntr - cntl , 0) * B;
}

signed main(){
    cin >> A >> B >> C >> N >> M;
    for(int i = 1 ; i <= N ; ++i) cin >> T[i];
    for(int i = 1 ; i <= M ; ++i) cin >> P[i];
    int L = 1 , R = 1e5;
    if(C == 1e16) for(int i = 1 ; i <= M ; ++i) R = min(R , T[i]);
    while(L < R){int mid = (L + R) >> 1; calc(mid) < calc(mid + 1) ? R = mid : L = mid + 1;}
    cout << calc(L) << endl; return 0;
}

相逢是问候

sol

根据拓展欧拉定理,$c^{c^{c^{...^{a_i}}}} \mod p = c^{c^{c^{...^{a_i}}}
mod\ \varphi(p)}$(当然这里省略了最后可能需要加上的$\varphi(p)$),那么我们不断令$p = \varphi(p)$,直到$p=1$,设做这样的操作的次数为$count$,则当某一个位置被操作$count+1$次之后值就被固定了(值得注意的是这里一定是$count+1$,因为$a_i$可能为$0$,但是$c^{a_i}$不可能为$0$).

那么我们维护线段树,当某一个区间内所有数的操作次数都$\geq count + 1$就不做操作,否则向下递归.当到达叶子节点时暴力更新,这样的复杂度是$O(n\ log^2p\ logw)$的,可以通过$90$分.

最后可以发现快速幂中的底数和我们需要取模的数都是给定的,所以可以用一个常见的$O(\sqrt p)-O(1)$的快速幂方法:对于一个给定的$p$,设$f_j$表示$c^j \mod p$,$g_j$表示$c^{Sj} \mod p$,其中$S = \sqrt{p}$,那么$c^k \mod p = f_{k \mod S} \times g_{k / S} \mod p$.

在预处理$f$和$g$数组的同时记录一下在不取模的情况下快速幂的实际值是否$\geq p$就可以判断要不要在最后加上一个$p$.

#include<bits/stdc++.h>
using namespace std;

#define int long long
const int _ = 5e4 + 3; int N , P , M , C , T , arr[_]; vector < int > mu;
int pow1[61][_] , pow2[61][_]; bool flg1[61][_] , flg2[61][_];

int poww(int a , int b , int p){
    int times = 1; bool flg = 0;
    while(b){
        if(b & 1){flg |= times * a >= p; times = times * a % p;}
        flg |= a * a >= p; a = a * a % p; b >>= 1;
    }
    return times + (p != P && flg) * p;
}

namespace segt{
    int cnt[_] , sum[_ << 2]; bool allv[_ << 2];

#define mid ((l + r) >> 1)
#define lch (x << 1)
#define rch (x << 1 | 1)

    void init(int x , int l , int r){
        if(l == r){cin >> arr[l]; sum[x] = arr[l]; return;}
        else{init(lch , l , mid); init(rch , mid + 1 , r); sum[x] = sum[lch] + sum[rch];}
    }

    void modify(int x , int l , int r , int L , int R){
        if(allv[x] || l > R || r < L) return;
        if(l == r){
            ++cnt[l]; int val = poww(C , arr[l] , mu[cnt[l] - 1]);
            for(int i = cnt[l] - 2 ; i >= 0 ; --i){
                int p = val % T , q = val / T;
                val = pow1[i][p] * pow2[i][q] % mu[i] + (bool)i * (flg1[i][p] || flg2[i][q] || pow1[i][p] * pow2[i][q] >= mu[i]) * mu[i];
            }
            sum[x] = val; allv[x] = mu[cnt[l] - 1] == 1; return;
        }
        modify(lch , l , mid , L , R); modify(rch , mid + 1 , r , L , R);
        allv[x] = allv[lch] & allv[rch]; sum[x] = sum[lch] + sum[rch];
    }

    int qry(int x , int l , int r , int L , int R){
        if(l >= L && r <= R) return sum[x];
        int sum = 0;
        if(mid >= L) sum = qry(lch , l , mid , L , R);
        if(mid < R) sum += qry(rch , mid + 1 , r , L , R);
        return sum;
    }
}

int poww(int a , int b , int p , bool &flg){
    int times = 1;
    while(b){
        if(b & 1){flg |= times * a >= p; times = times * a % p;}
        flg |= a * a >= p; a = a * a % p; b >>= 1;
    }
    return times;
}

void initmu(){
    mu.push_back(P); T = sqrt(2 * P) + 1;
    while(*--mu.end() != 1){
        int t = *--mu.end() , tmp = t , id = mu.size() - 1;
        pow1[id][0] = pow2[id][0] = 1;
        pow1[id][1] = poww(C , 1 , t , flg1[id][1]); pow2[id][1] = poww(C , T , t , flg2[id][1]);
        for(int i = 2 ; i <= T ; ++i){
            pow1[id][i] = pow1[id][i - 1] * pow1[id][1] % t;
            pow2[id][i] = pow2[id][i - 1] * pow2[id][1] % t;
            flg1[id][i] = flg1[id][i - 1] | (pow1[id][i - 1] * pow1[id][1] >= t);
            flg2[id][i] = flg2[id][i - 1] | (pow2[id][i - 1] * pow2[id][1] >= t);
        }
        for(int i = 2 ; i * i <= tmp ; ++i)
            if(tmp % i == 0){
                t = t / i * (i - 1); while(tmp % i == 0) tmp /= i;
            }
        if(tmp - 1) t = t / tmp * (tmp - 1);
        mu.push_back(t);
    }
}

signed main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    ios::sync_with_stdio(0); cin >> N >> M >> P >> C; segt::init(1 , 1 , N); initmu();
    for(int i = 1 ; i <= M ; ++i){
        int tp , l , r; cin >> tp >> l >> r;
        if(tp) printf("%lld\n" , segt::qry(1 , 1 , N , l , r) % P);
        else segt::modify(1 , 1 , N , l , r);
    }
    return 0;
}

组合数问题

sol

设$f_{i,j}$表示$\sum\limits_{p \in [0,i] , p \mod k = j}C_{i}^p$,转移考虑$C_i^j = C_{i-1}^j+C_{i-1}^{j-1}$,就有$f_{i,j} = f_{i-1,(j+k-1) \mod k} + f_{i-1,j}$,答案是$f_{n,r}$.

不难发现这个东西可以矩阵转移,套一个矩阵快速幂即可.复杂度$O(k^3logn)$.

#include<bits/stdc++.h>
//this code is written by Itst
using namespace std;

#define int long long
int N , P , R , K;

struct matrix{
    int a[50][50];
    matrix(){memset(a , 0 , sizeof(a));}
    int* operator [](int x){return a[x];}
    matrix operator *(matrix b){
        matrix c;
        for(int i = 0 ; i < K ; ++i)
            for(int j = 0 ; j < K ; ++j)
                for(int k = 0 ; k < K ; ++k)
                    c[i][k] = (c[i][k] + 1ll * a[i][j] * b[j][k]) % P;
        return c;
    }
}S , T;

signed main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    //freopen("out","w",stdout);
#endif
    cin >> N >> P >> K >> R; N *= K;
    S[0][0] = 1;
    for(int i = 0 ; i < K ; ++i)
        ++T[i][i] , ++T[i][(i + 1) % K];
    while(N){
        if(N & 1) S = S * T;
        T = T * T; N >>= 1;
    }
    cout << S[0][R];
    return 0;
}

摧毁树状图

sol

题目相当于选出两条至多在一个节点相交的路径使得将这些点删掉之后连通块数量最大.以下不作说明的情况下均认为$1$为根.

首先对于每一个点树形DP得到$mxlen_i , mxnum_i$,$mxlen_i$表示从点$i$向下延伸出一条路径能够在点$i$的子树中获得的最大连通块数量,$mxnum_i$表示对于点$i$子树中的所有路径,设路径深度最浅的点为$x$,则在$x$子树中删除这条路径能够获得的最大连通块数量的最大值.

然后再对于每一个点通过换根DP求出$uplen_i , upnum_i$,$uplen_i$表示以$fa_i$为原树的根,去掉点$i$所在子树,从$fa_i$向下延伸出一条路径能够获得的最大连通块数量,$upnum_i$则表示在同样的情况下对于$fa_i$子树内的所有路径,设路径深度最浅的点为$x$,则在$x$子树中删除这条路径能够获得的最大连通块数量的最大值.

接下来分三种情况讨论:

A.两条路径距离最近的点的距离为$1$:这两个点一定是一条边的两端.我们枚举边,相当于枚举$x$,考虑边$(x,fa_x)$.对于这种情况一定是一条路径在$x$的子树中,一条路径在以$fa_x$为根去掉$x$所在子树构成的树中,两者的最大连通块数量正好对应$mxnum_x$和$upnum_x$.所以用$mxnum_x+upnum_x$更新答案即可;

B.两条路径距离最近的点的距离为$0$:这个点只会有一个,考虑枚举这个点$x$.以$x$为树根,那么相当于需要在$x$所有儿子的子树中选出$2 \sim 4$个子树,每一个子树贡献一条从其内部到$x$的路径,使得连通块数量最大.因为我们预处理了$mxlen_x$和$uplen_x$,所以直接把所有这样的值丢到堆里面去取前若干大贡献答案即可.

C.两条路径距离最近的点的距离$\geq 2$:考虑枚举距离最近的两个点的路径上的点$x$,以$x$为树根,那么相当于需要在$x$的所有儿子中选出两条路径使得连通块数量最大.同样预处理了$mxnum_x$和$upnum_x$所以把所有这样的值丢进堆里取前$2$大更新答案.

#include<bits/stdc++.h>
using namespace std;

int read(){
    int a = 0; char c = getchar(); bool f = 0;
    while(!isdigit(c)){f = c == '-'; c = getchar();}
    while(isdigit(c)){
        a = a * 10 + c - 48; c = getchar();
    }
    return f ? -a : a;
}

const int _ = 1e5 + 7;
vector < int > ch[_];
int N , ans , fa[_]; int mxl[_] , mxn[_] , upl[_] , upn[_];

void dfs1(int x){
    upl[x] = upn[x] = 0; int cnt = ch[x].size() - (x != 1); mxl[x] = 1; mxn[x] = 2;
    for(auto t : ch[x])
        if(t != fa[x]){
            fa[t] = x; dfs1(t); mxn[x] = max(mxn[x] , max(mxn[t] - cnt + 2 , mxl[x] + mxl[t]));
            mxl[x] = max(mxl[x] , mxl[t]);
        }
    mxl[x] += cnt - 1; mxn[x] += cnt - 2;
}

int p1[_] , p2[_] , s1[_] , s2[_];
void dfs2(int x){
    ans = max(ans , upn[x] + mxn[x]);
    int cnt = (int)ch[x].size() - 1;

    p1[0] = s1[ch[x].size() + 1] = 1; p2[0] = s2[ch[x].size() + 1] = 2;
    for(int i = 1 ; i <= ch[x].size() ; ++i){
        int t = ch[x][i - 1] , p = t == fa[x] ? upl[x] : mxl[t] , q = t == fa[x] ? upn[x] : mxn[t];
        p2[i] = max(p2[i - 1] , max(q - cnt + 2 , p1[i - 1] + p)); p1[i] = max(p1[i - 1] , p);
    }
    for(int i = ch[x].size() ; i ; --i){
        int t = ch[x][i - 1] , p = t == fa[x] ? upl[x] : mxl[t] , q = t == fa[x] ? upn[x] : mxn[t];
        s2[i] = max(s2[i + 1] , max(q - cnt + 2 , s1[i + 1] + p)); s1[i] = max(s1[i + 1] , p);
    }

    for(int i = 1 ; i <= ch[x].size() ; ++i)
        if(ch[x][i - 1] != fa[x]){
            int t = ch[x][i - 1]; upl[t] = max(p1[i - 1] , s1[i + 1]) + cnt - 1;
            upn[t] = max(max(p2[i - 1] , s2[i + 1]) , p1[i - 1] + s1[i + 1]) + cnt - 2;
        }

    for(int i = 1 ; i <= ch[x].size() ; ++i) if(ch[x][i - 1] != fa[x]) dfs2(ch[x][i - 1]);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    for(int T = read() , x = read() ; T ; --T){
        N = read(); for(int i = 1 ; i <= N ; ++i) ch[i].clear();
        for(int i = 1 ; i <= 2 * x ; ++i) read();
        for(int i = 1 ; i < N ; ++i){
            int a = read() , b = read(); ch[a].push_back(b); ch[b].push_back(a);
        }
        ans = 0; dfs1(1); dfs2(1);
        for(int i = 1 ; i <= N ; ++i)
            if(ch[i].size() >= 2){
                priority_queue < int > q;
                for(auto t : ch[i]) q.push(t == fa[i] ? upn[i] : mxn[t]);
                int sum = q.top(); q.pop(); sum += q.top(); q.pop();
                ans = max(ans , sum + 1); while(!q.empty()) q.pop();
                for(auto t : ch[i]) q.push(t == fa[i] ? upl[i] : mxl[t]);
                for(int i = 1 ; i <= 4 ; ++i) q.push(1);
                sum = 0; for(int i = 1 ; i <= 4 ; ++i){sum += q.top(); q.pop();}
                ans = max(ans , sum + (int)ch[i].size() - 4);
            }
        printf("%d\n" , ans);
    }
    return 0;
}

分手是祝愿

sol

不难发现对于一个确定的状态,最小步数和对于最小步数需要按的开关集合是固定的,且在摁了某个开关后,不会影响其他开关在最小步数中是否会被摁到.

设开始局面最小步数为$p$,设$f_i(i > K)$表示经过最小步数为$i$的局面的期望次数,那么$f_i = [i \neq K + 1]f_{i-1}\frac{N-i+1}{N} + [i \neq N]f_{i+1}\frac{i+1}{N} + [i == p]$.

把这些所有方程都加起来就可以得到$\frac{K+1}{N}f_{K+1} = 1$,进而可以求得所有的$f_i$.答案就是$\sum\limits_{i=K+1}^Nf_i$.

#include<bits/stdc++.h>
using namespace std;

const int _ = 1e5 + 3;
int N , K , val , jc = 1 , arr[_];

int poww(long long a , int b){
    int times = 1;
    while(b){
        if(b & 1) times = times * a % _;
        a = a * a % _; b >>= 1;
    }
    return times;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("in","r",stdin);
    freopen("out","w",stdout);
#endif
    cin >> N >> K; for(int i = 1 ; i <= N ; jc = 1ll * jc * i++ % _) cin >> arr[i];
    for(int i = N ; i ; --i)
        if(arr[i]){
            ++val;
            for(int j = 1 ; j * j <= i ; ++j)
                if(i % j == 0){arr[j] ^= 1; if(i / j != j) arr[i / j] ^= 1;}
        }
    if(val <= K){printf("%lld\n" , 1ll * val * jc % _); return 0;}
    int pre1 = 0 , pre2 = 1ll * N * poww(K + 1 , _ - 2) % _ , ans = pre2;
    for(int i = K + 1 ; i < N ; ++i){
        int p1 = 1ll * poww(N , _ - 2) * (N - i + 1) % _ , p3 = 1ll * poww(N , _ - 2) * (i + 1) % _;
        int now = (pre2 - 1ll * pre1 * p1 % _ + _ - (i == val)) * poww(p3 , _ - 2) % _;
        pre1 = pre2; pre2 = now; ans = (ans + now) % _;
    }
    cout << 1ll * (ans + K) * jc % _; return 0;
}

寿司餐厅

sol

看到选择什么就要选择什么、选择有代价和收益的问题,考虑最大权闭合子图.那么我们只需要考虑每一个点的代价和收益以及限制关系.

首先,选择$d_{i,j}(i

对于$d_{i,i}$,考虑$m = 0$的情况,此时选择第$i$个寿司的收益就是$d_{i,i}-ca_i$,也是相对明确的.

当$m \neq 0$时相当于每一个种类的寿司选择第一个时会有$mx^2$的贡献.考虑对所有种类再建一个点,选择该种类的寿司就必须选择该种类,选择第$x$个种类的代价是$mx^2$.这样寿司的代价就可以明确地表示在图中了,跑最大权闭合子图即可得到答案.

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
//This code is written by Itst
using namespace std;

inline int read(){
    int a = 0;
    char c = getchar();
    bool f = 0;
    while(!isdigit(c) && c != EOF){
        if(c == '-')
            f = 1;
        c = getchar();
    }
    if(c == EOF)
        exit(0);
    while(isdigit(c)){
        a = (a << 3) + (a << 1) + (c ^ '0');
        c = getchar();
    }
    return f ? -a : a;
}

namespace flow{
    const int MAXN = 1e5 + 7 , MAXM = 1e6 + 7;
    struct Edge{
        int end , upEd , f , c;
    }Ed[MAXM];
    int head[MAXN];
    int N , M , S , T , cntEd = 1;
    queue < int > q;

    inline void addEd(int a , int b , int c , int d = 0){
        Ed[++cntEd].end = b;
        Ed[cntEd].upEd = head[a];
        Ed[cntEd].f = c;
        Ed[cntEd].c = d;
        head[a] = cntEd;
    }

    inline void addE(int a , int b , int c , int d = 0 , bool f = 0){
        addEd(a , b , c , d); addEd(b , a , c * f , -d);
    }

    int cur[MAXN] , dep[MAXN];

    inline bool bfs(){
        while(!q.empty())
            q.pop();
        q.push(S);
        memset(dep , 0 , sizeof(dep));
        dep[S] = 1;
        while(!q.empty()){
            int t = q.front();
            q.pop();
            for(int i = head[t] ; i ; i = Ed[i].upEd)
                if(Ed[i].f && !dep[Ed[i].end]){
                    dep[Ed[i].end] = dep[t] + 1;
                    if(Ed[i].end == T){
                        memcpy(cur , head , sizeof(head));
                        return 1;
                    }
                    q.push(Ed[i].end);
                }
        }
        return 0;
    }

    inline int dfs(int x , int mF){
        if(x == T)
            return mF;
        int sum = 0;
        for(int &i = cur[x] ; i ; i = Ed[i].upEd)
            if(Ed[i].f && dep[Ed[i].end] == dep[x] + 1){
                int t = dfs(Ed[i].end , min(mF - sum , Ed[i].f));
                if(t){
                    Ed[i].f -= t;
                    Ed[i ^ 1].f += t;
                    sum += t;
                    if(sum == mF)
                        break;
                }
            }
        return sum;
    }

    int Dinic(int s , int t){
        int ans = 0;
        S = s; T = t;
        while(bfs())
            ans += dfs(S , INF);
        return ans;
    }
}
int A[307] , lsh[307] , ind[307][307] , L , sum;

int main(){
#ifndef ONLINE_JUDGE
    freopen("in" , "r" , stdin);
    //freopen("out" , "w" , stdout);
#endif
    int N = read() , M = read();
    for(int i = 1 ; i <= N ; ++i)
        lsh[i] = A[i] = read();
    sort(lsh + 1 , lsh + N + 1);
    L = unique(lsh + 1 , lsh + N + 1) - lsh - 1;
    int S = 0 , T = N * (N + 1) / 2 + N + L + 1 , cnt = 0;
    for(int i = 1 ; i <= N ; ++i)
        for(int j = i ; j <= N ; ++j)
            ind[i][j] = ++cnt;
    for(int i = 1 ; i <= N ; ++i)
        for(int j = i ; j <= N ; ++j){
            int val = read();
            if(val > 0){
                sum += val;
                flow::addE(S , ind[i][j] , val);
            }
            else flow::addE(ind[i][j] , T , -val);
            if(i == j)
                flow::addE(ind[i][j] , cnt + i , INF);
            else{
                flow::addE(ind[i][j] , ind[i + 1][j] , INF);
                flow::addE(ind[i][j] , ind[i][j - 1] , INF);
            }
        }
    for(int i = 1 ; i <= N ; ++i){
        flow::addE(cnt + i , T , A[i]);
        flow::addE(cnt + i , cnt + N + lower_bound(lsh + 1 , lsh + L + 1 , A[i]) - lsh , INF);
    }
    for(int i = 1 ; i <= L ; ++i)
        flow::addE(cnt + N + i , T , M * lsh[i] * lsh[i]);
    cout << sum - flow::Dinic(S , T);
    return 0;
}

原文地址:https://www.cnblogs.com/Itst/p/11518660.html

时间: 2024-10-01 07:05:33

六省联考2017的相关文章

P3746 [六省联考2017]组合数问题

P3746 [六省联考2017]组合数问题 \(dp_{i,j}\)表示前\(i\)个物品,取的物品模\(k\)等于\(r\),则\(dp_{i,j}=dp_{i-1,(j-1+k)%k}+dp_{i-1,j}\) \(dp_{i,0},dp_{i,1},dp_{i,2}.....dp_{i,k-1}\) \(\Longrightarrow\) \(dp_{i+1,0},dp_{i+1,1},dp_{i+1,2}.....dp_{i+1,k-1}\) 仔细想想,你能构造出矩阵的 #include

[luogu] P3745 [六省联考2017]期末考试 (贪心)

P3745 [六省联考2017]期末考试 题目描述 有 \(n\) 位同学,每位同学都参加了全部的 \(m\) 门课程的期末考试,都在焦急的等待成绩的公布. 第 \(i\) 位同学希望在第 \(t_i\)? 天或之前得知所有课程的成绩.如果在第 \(t_i\) 天,有至少一门课程的成绩没有公布,他就会等待最后公布成绩的课程公布成绩,每等待一天就会产生 \(C\) 不愉快度. 对于第 \(i\) 门课程,按照原本的计划,会在第 \(b_i\)? 天公布成绩. 有如下两种操作可以调整公布成绩的时间:

bzoj千题计划265:bzoj4873: [六省联考2017]寿司餐厅

http://www.lydsy.com/JudgeOnline/problem.php?id=4873 选a必选b,a依赖于b 最大权闭合子图模型 构图: 1.源点 向 正美味度区间 连 流量为 美味度 的边 2.负美味度区间 向 汇点 连 流量为 美味度的绝对值 的边 3.区间[i,j] 向 区间[i+1,j].区间[i,j-1] 连 流量为 inf 的边 4.区间[i,i] 向 寿司i 连 流量为 inf 的边 5.寿司i 向 汇点 连 流量为 寿司代号 的边 6.寿司i 向 它的代号 连

bzoj千题计划266:bzoj4872: [六省联考2017]分手是祝愿

http://www.lydsy.com/JudgeOnline/problem.php?id=4872 一种最优解是 从大到小灯有亮的就灭掉 最优解是唯一的,且关灯的顺序没有影响 最优解 对每个开关至多操作1次,(连带着的灯的亮灭改变不算) 设最优解 需要操作cnt次,那么就有cnt盏灯是正确的选择 设 f[i] 表示 有i种正确的选择  变为 有i-1种正确的选择 的 期望次数 那么在n盏灯中,有i盏灯操作1次 就可以 减少一次正确选择 有n-i盏灯是错误的选择,选了它还要把它还原,还原它也

[BZOJ4869][六省联考2017]相逢是问候(线段树+扩展欧拉定理)

4869: [Shoi2017]相逢是问候 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1313  Solved: 471[Submit][Status][Discuss] Description Informatikverbindetdichundmich. 信息将你我连结.B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以 分为两种:0 l r表示将第l个到第r个数(al,al+1,...,ar)中的每

[六省联考2017]相逢是问候

相逢是问候 2017-09-09 Description Informatikverbindetdichundmich. 信息将你我连结.B君希望以维护一个长度为n的数组,这个数组的下标为从1到n的正整数.一共有m个操作,可以分为两种:0 l r表示将第l个到第r个数(al,al+1,...,ar)中的每一个数ai替换为c^ai,即c的ai次方,其中c是输入的一个常数,也就是执行赋值ai=c^ai1 l r求第l个到第r个数的和,也就是输出:sigma(ai),l<=i<=rai因为这个结果可

[六省联考2017]期末考试

4868: [Shoi2017]期末考试 2017-09-03 Description 有n位同学,每位同学都参加了全部的m门课程的期末考试,都在焦急的等待成绩的公布.第i位同学希望在第ti天或之前得知所.有.课程的成绩.如果在第ti天,有至少一门课程的成绩没有公布,他就会等待最后公布成绩的课程公布成绩,每等待一天就会产生C不愉快度.对于第i门课程,按照原本的计划,会在第bi天公布成绩.有如下两种操作可以调整公布成绩的时间:1.将负责课程X的部分老师调整到课程Y,调整之后公布课程X成绩的时间推迟

[六省联考2017]寿司餐厅

题链 这道题长着网络流的数据范围. 最大权闭合子图问题 跑最小割 #include<bits/stdc++.h> #define eho(x) for(int& i=hed[x];~i;i=net[i]) #define Eho(x) for(int i=head[x];~i;i=net[i]) #define N 52607 #define M 3500007 #define NN 1007 #define sight(c) (c<='9'&&c>='0'

bzoj千题计划271:bzoj4869: [六省联考2017]相逢是问候

http://www.lydsy.com/JudgeOnline/problem.php?id=4869 欧拉降幂+线段树,每个数最多降log次,模数就会降为1 #include<cmath> #include<cstdio> #include<iostream> using namespace std; #define N 50001 int n,m,p,c; int a[N]; int sum[N<<2]; int tag[N<<2]; in

洛谷P3747 [六省联考2017]相逢是问候

传送门 题解 扩展欧拉定理. 线段树维护,已经全改到底了的节点就不管,不然暴力修改下去. //Achen #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<vector> #include<cstdio> #include<queue> #include<cmath> const int N=5