2020 CCPC-Wannafly Winter Camp Day6


PTA
牛客

A. Convolution

題意:
給出序列\(a_{1...n}\),求\(\displaystyle \sum_{i=1}^n\sum_{j=1}^n2^{a_ia_j}\)
\(n\leq 10^5,a_i\leq 10^5\)

思路:

\[\begin{aligned} &\sum_{i=1}^n\sum_{j=1}^n2^{a_ia_j}\\ =&\sum_{i=1}^n\sum_{j=1}^n(\sqrt{2})^{2a_ia_j}\\ =&\sum_{i=1}^n\sum_{j=1}^n(\sqrt{2})^{(a_i+a_j)^2-a_i^2-a_j^2}\\ =&\sum_{k}(\sqrt{2})^{k^2}\sum_{a_i+a_j=k}(\sqrt{2})^{-a_i^2-a_j^2} \end{aligned} \]

有了這個之后,我們構造多項式\(\displaystyle f(x)=\sum_{i=0}^{n}(\sqrt{2})^{-a_i^2}x^{a_i}\)
對於第二個求和式,直接卷積計算即可。
\(2\)的二次剩余可直接暴力得到。
代碼如下:

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/18 21:10:44
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 4e5 + 5, P = 998244353, G = 3, Gi = 332748118;
const int p = 116195171;
int n, m, r[N];
ll a[N], b[N];//注意空間要開四倍
ll qpow(ll a, ll k) {
    ll ans = 1;
    while(k) {
        if(k & 1) ans = (ans * a ) % P;
        a = (a * a) % P;
        k >>= 1;
    }
    return ans;
}
void NTT(ll *A, int type, int n) {
    for(int i = 0; i < n; i++)
        if(i < r[i]) swap(A[i], A[r[i]]);
    for(int mid = 1; mid < n; mid <<= 1) {
        ll Wn = qpow( type == 1 ? G : Gi , (P - 1) / (mid << 1)); //Wn = g ^ ((p - 1) / n)  (mod p)
        for(int j = 0; j < n; j += (mid << 1)) {
            ll w = 1;
            for(int k = 0; k < mid; k++, w = (w * Wn) % P) {
                 int x = A[j + k], y = w * A[j + k + mid] % P;
                 A[j + k] = (x + y) % P,
                 A[j + k + mid] = (x - y + P) % P;
            }
        }
    }
    if(type == -1) {
        ll inv = qpow(n, P - 2);
        for(int i = 0; i < n; i++) A[i] = A[i] * inv % P;   
    }
}
void solve(ll *a, ll *b) {
    int lim = 1, L = 0;
    while(lim <= n + m) lim <<= 1, L++;
    for(int i = 0; i < lim; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
    for(int i = n + 1; i < lim; i++) a[i] = 0;  //a,b need init
    for(int i = m + 1; i < lim; i++) b[i] = 0;
    NTT(a, 1, lim); NTT(b, 1, lim);
    for(int i = 0; i < lim; i++) a[i] = a[i] * b[i] % P;
    NTT(a, -1, lim);
}

int c[N];

void run(){
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> c[i];
    for(int i = 1; i <= n; i++) {
        a[c[i]] = (a[c[i]] + qpow(qpow(p, 1ll * c[i] * c[i]), P - 2)) % P;
    }
    for(int i = 1; i <= n; i++) {
        b[c[i]] = a[c[i]];
    }
    n = m = *max_element(c + 1, c + n + 1) + 1;
    solve(a, b);
    int ans = 0;
    for(int i = 0; i <= 2 * n - 2; i++) {
        int res = 1ll * qpow(p, 1ll * i * i) * a[i] % P;
        ans = (ans + res) % P;
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    run();
    return 0;
}

C. 酒館戰棋

貪心即可。

Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int MAXN = 1e3+5,MAXM = 1e6+5,MOD = 1e9+7,INF = 0x3f3f3f3f,N=2e5;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const db eps = 1e-7;
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pii pair<int,int>
#define vii vector<pii>
#define vi vector<int>
#define x first
#define y second
using namespace std;

int T,n,A,B,C,D;
char s[MAXN];
int solve1(int a,int b,int c,int d){
    int ans=0;
    for(int i=0;i<n;i++){
        if(s[i]=='0'){
            if(c + d){
                if(d)d--,c++;
            }else if(a+b){
                if(b)b--,a++;
            }
        }else{
            if(c+d){
                if(c)c--,ans++;
                else c++,d--;
            }else if(a+b){
                if(a)a--,ans++;
                else b--,a++;
            }
        }
    }
    return ans;
}

int solve2(int a,int b,int c,int d){
    int ans=0;
   for(int i=0;i<n;i++){
        if(s[i]=='0'){
            if(c + d){
                if(!c)d--,c++;
            }else if(a+b){
                if(!a)b--,a++;
            }
        }else{
            if(c+d){
                if(!d)c--,ans++;
                else c++,d--;
            }else if(a+b){
                if(!b)a--,ans++;
                else b--,a++;
            }
        }
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(false);cin.tie(0);
    cin>>T;
    while(T--){
        cin>>n>>A>>B>>C>>D;
        cin>>s;
        cout<<solve1(A,B,C,D)<<' '<<solve2(A,B,C,D)<<'\n';
    }
    return 0;
}

F. 圖與三角形

容斥一下。
通過枚舉角算出不合法的三角形個數,然后用總答案減去即可。
最后要除以一個\(2\),因為一個三角形不合法,就會存在兩個角的兩邊不同色。

Code
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define REPE(i,a,b) for(int i=(a); i<=(b); i++)
#define MAXN 5007
typedef long long ll;
typedef unsigned long long ull;
int rc[MAXN], bc[MAXN];
ull ans;
int main() {
	memset(rc,0,sizeof rc);
	memset(bc,0,sizeof bc);
	int n; scanf("%d", &n);
	int A,B,C,P,D; scanf("%d%d%d%d%d", &A, &B, &C, &P, &D);
	REPE(i,1,n) REPE(j,i+1,n) {
		if(((ll)A*(i+j)*(i+j)+(ll)B*(i-j)*(i-j)+C)%P>D) {
			bc[i]++, bc[j]++;
		} else {
			rc[i]++, rc[j]++;
		}
	}
	ans=0;
	REPE(i,1,n) {
		ans+=bc[i]*rc[i];
	}
	ans/=2;
	ans = (ull)n*(n-1)*(n-2)/6-ans;
	printf("%llu\n", ans);
}

G. 單調棧

顯然若\(f(1)\)一定為\(1\),對於所有\(f\)值相同的位置,我們依次從小到大倒序來放置即可。
然后將所有的\(f\)值減一,再重復執行以上操作即可。
貪心的正確性:

  • \(f(1)=1\)顯然,然后對於所有為\(1\)的位置,若存在\(i,j,i<j\),有\(a_i<a_j\),那么必然\(f_i<f_j\),所以必然是倒序。因為要求字典序最小,所以依次放置。

  • 對於多個\(f=-1\),因為字典序最小,我們能不處理則不處理,否則會使前面的增大。

代碼如下:

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/17 20:53:27
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 100 + 5;

int n;
int f[N], ans[N];
bool chk[N];

void run(){
    memset(chk, 0, sizeof(chk));
    int Min = 1;
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> f[i];
    while(1) {
        int fir = -1;
        for(int i = 1; i <= n; i++) {
            if(!chk[i]) {
                if(f[i] == -1) f[i] = 1;
                fir = i; break;
            }
        }
        if(fir == -1) break;
        for(int i = n; i >= 1; i--) if(!chk[i]) {
            if(f[i] == 1) {
                chk[i] = true;
                ans[i] = Min++;
            } else if(f[i] > 1) {
                f[i] -= 1; 
            }
        }
    }
    for(int i = 1; i <= n; i++) cout << ans[i] << " \n"[i == n];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

H. 異或詢問

題意:
給出一個序列\(a_{1...n}\),定義\(f(x)\)為有幾個\(a_i\)小於等於\(x\)
現有\(q\)個詢問,每次給定\(l,r,x\),需要求\(\displaystyle\sum_{i=l}^rf^2(i\ xor\ x)\)

思路:

  • 顯然可以將詢問拆為兩個前綴相減,那么現在只需要考慮求\(\sum_{i=0}^rf^2(i\ xor\ x)\)
  • 因為\(i\)的變化為\(0\rightarrow r\),我們可以類似於數位\(dp\)那樣來考慮:假設當前\(r\)最高位為\(w\),也就是說\(bit(r,w)=1\),那么這位取\(0\)的話,后面可以任意取,所以\(i\ xor\ r\)此時為連續的一段區間;如果這一位取\(1\),那么就枚舉下一位再類似考慮就行。
  • 也就是說我們按二進制位從高到低考慮,將\(i\ xor\ x,0\leq i\leq r\)可以拆分為若干個連續的區間,接下來考慮的就是怎么求\(\sum_{i=l}^rf(i)\)
  • 這個就很好求了,直接預處理后二分即可。

細節見代碼:

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/19 11:47:00
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5, MOD = 998244353;

int n, q;
int a[N];
vector <pii> b;
ll pre[N], w[N];

int sum(int x) {
    int p = upper_bound(all(b), MP(x, INF)) - b.begin() - 1;
    if(p < 0) return 0;
    return ((p > 0 ? pre[p - 1] : 0) + 1ll * (x - b[p].fi + 1) * w[p] % MOD) % MOD;
}

int solve(int n, int x) {
    int res = 0;
    for(int i = 29; i >= 0; i--) {
        if(n >> i & 1) {
            int t = (n ^ x) >> i << i;
            int st = t ^ (1 << i);
            int ed = st + (1 << i) - 1;
            res = (1ll * res + sum(ed) - sum(st - 1) + MOD) % MOD;
        }
    }
    int t = n ^ x;
    res = (1ll * res + sum(t) - sum(t - 1) + MOD) % MOD;
    return res;
}

void run() {
    for(int i = 1; i <= n; i++) cin >> a[i];
    sort(a + 1, a + n + 1);
    for(int i = 1, j; i <= n; i = j + 1) {
        j = i;
        while(j < n && a[j + 1] == a[j]) ++j;
        b.push_back(MP(a[i], j - i + 1));
    }
    for(int i = 0; i < sz(b); i++) {
        if(i == 0) w[i] = b[i].se;
        else w[i] = w[i - 1] + b[i].se;
    }
    for(int i = 0; i < sz(b); i++) {
        w[i] = 1ll * w[i] * w[i] % MOD;   
    }
    for(int i = 0; i < sz(b); i++) {
        if(i + 1 < sz(b)) {
            if(i == 0) pre[i] = 1ll * (b[i + 1].fi - b[i].fi) * w[i] % MOD;
            else pre[i] = (pre[i - 1] + 1ll * (b[i + 1].fi - b[i].fi) * w[i] % MOD) % MOD;
        }
    }
    while(q--) {
        int l, r, x; cin >> l >> r >> x;
        int ans = (solve(r, x) - solve(l - 1, x) + MOD) % MOD;   
        cout << ans << '\n';
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n >> q) run();
    return 0;
}

I. 變大!

題意:
給出一個序列\(a[1...n]\),每次可以選擇一個\(i(2\leq i<n)\),然后將\(a[i-1],a[i],a[i+1]\)都變為\(max(a[i-1],a[i],a[i+1])\)
現在進行\(k\)次這樣的操作,目標是最大化\(\sum_{i=1}^n a_i\)
現在對於\(k=1...n\)依次輸出最終答案。
\(n\leq 100\)

思路:
顯然最后的答案都是一段一段的形式,每一段的值都為該段最大值。
然后還有一個性質:

  • 對於長度為\(l\)的一段區間,需要將其全變為最大值的操作次數為\(\lfloor\frac{l}{2}\rfloor\)

那么我們枚舉每個數,再枚舉其分段,然后做個簡單\(dp\)就行了。
時間復雜度\(O(n^3)\)

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/2/17 21:24:13
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 50 + 5, M = 20 + 5;

int n;
int a[N];
int dp[N][N];

void run(){
    memset(dp, 0, sizeof(dp));
    cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i <= n; i++) {
        int mx = a[i];
        for(int j = i; j >= 1; j--) {
            mx = max(mx, a[j]);
            int c = (i - j + 1) / 2;
            for(int k = c; k <= n; k++) {
                dp[i][k] = max(dp[i][k], dp[j - 1][k - c] + (i - j + 1) * mx);   
            }
        }
    }
    for(int i = 1; i <= n; i++) cout << dp[n][i] << " \n"[i == n];
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    int T; cin >> T;
    while(T--) run();
    return 0;
}

J. K重排列

題意:
對於一個排列\(p[1\cdots n]\),設\(p^k[i]=p[p^{k-1}[i]]\),且\(p^1[i]=p[i]\)
如果存在一個\(k\),使得對於所有的\(i\)都有\(p^k[i]=i\),那么\(k\)\(p\)的一個周期。
最后統計滿足\(k\)為其一個周期的排列個數。

思路:
題解已經說的很清楚了,在比賽的時候考慮的是將\(n\)個點划分為若干個循環,每個循環的長度整除\(k\)
然后想的是直接搜索,感覺問題應該不大...
直接附上題解說的吧。

給出暴力的代碼:

Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int MAXN = 50+5,MAXM = 1e6+5,MOD = 998244353,INF = 0x3f3f3f3f,N=2e5;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const db eps = 1e-7;
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pii pair<int,int>
#define vii vector<pii>
#define vi vector<int>
#define x first
#define y second
using namespace std;
int n,T;
ll ans=0,K,fact[MAXN],inv[MAXN];

ll qpow(ll a,ll b){
    ll ans=1;
    for(;b;b>>=1,a=a*a%MOD)if(b&1)ans=ans*a%MOD;
    return ans;
}
ll C(int a,int b){
    if(a<b)return 0;
    if(a==b || b==0)return 1;
    return fact[a] * inv[a-b]%MOD*inv[b]%MOD;
}
void dfs(int sum,int pre,ll res,int cnt){
    if(!sum){
        res = res * inv[cnt]%MOD;
        ans = (ans + res)%MOD;
        //cout<<cnt<<' '<<res<<'\n';
        return ;
    }
    for(int i=pre;i<=sum;i++){
        if(K%i==0){
            //cout<<sum<<' '<<i<<' '<<C(sum,i)<<'\n';
            ll tmp = res * C(sum,i)%MOD*fact[i-1]%MOD;
            if(i != pre){
                tmp = tmp * inv[cnt] % MOD;
                dfs(sum-i,i,tmp,1);
            }else dfs(sum-i,i,tmp,cnt+1);
        }
    }
}
int main(){
    ios::sync_with_stdio(false);cin.tie(0);
    fact[1] = fact[0] = 1;
    for(int i=2;i<=50;i++)fact[i] = fact[i-1]*i%MOD;
    inv[50] = qpow(fact[50],MOD-2);
    for(int i=49;i>0;i--)inv[i] = inv[i+1]*(i+1)%MOD;
    inv[0]=1;
    cin>>T;
    while(T--){
        cin>>n>>K;
        ans = 0;
        dfs(n,1,1,0);
        cout<<ans<<'\n';
    }
    return 0;
}

K. 最大權值排列

接下來簽到四連。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/1/17 13:32:46
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;

int n;

void run(){ 
    int now = 1;
    for(int i = 1; i <= n; i++) {
        cout << now << ' ';
        if(i <= (n - 1) / 2) now += 2;   
        else {
            if(now & 1) {
                if(n & 1) --now;
                else ++now;
            }
            else now -= 2;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}

L. 你嚇到我的馬了.jpg

BFS。

Code
#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
const int MAXN = 1e2+5,MAXM = 1e6+5,MOD = 1e9+7,INF = 0x3f3f3f3f,N=2e5;
const ll INFL = 0x3f3f3f3f3f3f3f3f;
const db eps = 1e-7;
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define mid l + ((r-l)>>1)
#define pii pair<int,int>
#define vii vector<pii>
#define vi vector<int>
#define x first
#define y second
using namespace std;

int n,m;
int dx[8] = {-2,-2,2,2,-1,1,-1,1};
int dy[8] = {-1,1,-1,1,-2,-2,2,2};
int dx2[8] = {-1,-1,1,1,0,0,0,0};
int dy2[8] = {0,0,0,0,-1,-1,1,1};
char mp[MAXN][MAXN];
int vis[MAXN][MAXN];
inline bool bound(int x,int y){
    return x>=1&&x<=n&&y>=1&&y<=m;
}
int main(){
    ios::sync_with_stdio(false);cin.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>(mp[i]+1);
    }
    int sx,sy;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(mp[i][j]=='M'){
                sx = i,sy=j;
            }
        }
    }
    queue<pii> q;
    q.push({sx,sy});
    vis[sx][sy] = 1;
    pii nw;
    //cout<<sx<<' '<<sy<<'\n';
    while(!q.empty()){
        pii a = q.front();q.pop();
        for(int i=0;i<8;i++){
            nw.x = a.x + dx[i];
            nw.y = a.y + dy[i];
            if(bound(nw.x,nw.y) && mp[a.x+dx2[i]][a.y+dy2[i]]!='X' && mp[nw.x][nw.y] != 'X' && !vis[nw.x][nw.y]){
                q.push(nw);
                vis[nw.x][nw.y] = vis[a.x][a.y] + 1;
                //cout<<nw.x<<' '<<nw.y<<' '<<vis[nw.x][nw.y]<<'\n';
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(vis[i][j])cout<<vis[i][j]-1<<" \n"[j==m];
            else cout<<"-1"<<" \n"[j==m];
        }
    }
    return 0;
}

M. 自閉

模擬。

Code
#include<bits/stdc++.h>
using namespace std;
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define G0(x) memset(x,0,sizeof(x))
#define MAXN 107
bool sub[MAXN];
bool ac[MAXN][17];
int acc[MAXN];
int was[MAXN][17];
int wac[MAXN][17];
int accnt[17];
int zb[MAXN];
int n,m,W;
int main() {
	scanf("%d%d%d", &n, &m, &W);
	G0(sub),G0(ac),G0(was),G0(wac),G0(accnt),G0(zb),G0(acc);
	REP(i,0,W) {
		int x,y,c; scanf("%d%d%d", &x, &y, &c); x--,y--;
		sub[x]=1;
		if(c) {
			if(!ac[x][y]) accnt[y]++,ac[x][y]=1,acc[x]++;
			wac[x][y]=0;
		} else {
			wac[x][y]++;
			was[x][y]=max(was[x][y],wac[x][y]);
		}
	}
	REP(i,0,n) {
		if(!sub[i]) {
			zb[i]=998244353;
			continue;
		} else if(!acc[i]) {
			zb[i]=1000000;
			continue;
		} else if(acc[i]==m) {
			zb[i]=0;
			continue;
		}
		REP(j,0,m) {
			if(!ac[i][j] && accnt[j]>0) {
				zb[i]+=20;
			}
			if(!ac[i][j] && accnt[j]>=n/2) {
				zb[i]+=10;
			}
			zb[i]+=was[i][j]*was[i][j]*((!ac[i][j])+1);
		}
	}
	REP(i,0,n) {
		printf("%d\n", zb[i]);
	}
	
}

N. 合並!

稍微手模一下就可以發現怎么合並答案都是一樣。

Code
/*
 * Author:  heyuhhh
 * Created Time:  2020/1/17 13:05:18
 */
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
  #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  void err() { std::cout << '\n'; }
  template<typename T, typename...Args>
  void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
  #define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2000 + 5;

int n;
int a[N];

void run(){
    for(int i = 1; i <= n; i++) cin >> a[i];
    ll ans = 0;
    for(int i = 1; i <= n; i++) {
        for(int j = i + 1; j <= n; j++) {
            ans += a[i] * a[j];
        }
    }
    cout << ans << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(20);
    while(cin >> n) run();
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM