枚舉一個數%K的值而後統計另兩個ios
#include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi first #define se second #define MAXN 200005 #define pb push_back //#define ivorysi using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int N,K; int cnt[200005]; int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(N);read(K); int64 ans = 0; for(int i = 1 ; i <= N ; ++i) { cnt[i % K]++; } for(int i = 0 ; i < K ; ++i) { if((K - i) * 2 % K == 0) { ans += 1LL * cnt[i] * cnt[(K - i) % K] * cnt[(K - i) % K]; } } out(ans);enter; return 0; }
感受本身萬分智障,沒切掉,被學弟吊着打呀qwqc++
咱們連出一條邊全爲\(2^0\)到\(2^(r - 1)\)的鏈出來,\(2^r\)是L的最高位
而後咱們經過增長一些點到N的邊權X,使得數量爲L且合法便可。。ui
#include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define pb push_back #define eps 1e-8 //#define ivorysi using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 - '0' + c; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int L,N; void add(int u,int v,int c) { out(u);space;out(v);space;out(c);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif read(L); int r; for(r = 20 ; r >= 0 ; --r) { if(L & (1 << r)) break; } N = r + 1;out(N);space;int M = r * 2 + __builtin_popcount(L) - 1;out(M);enter; for(int i = 1 ; i <= N - 1 ; ++i) { add(i,i + 1,(1 << i - 1));add(i,i + 1,0); } for(int i = 1 ; i <= N - 1 ; ++i) { if(L & (1 << i - 1)) { L ^= (1 << i - 1); add(i,N,L); } } }
計數題spa
加和的限制至關於有幾個數兩個中只能出現一個
算一個dp[i][j]表示把i個數分紅j段,每一段兩種染色方式染色的方案數rest
而後枚舉有多少數用來給兩種方式染色,有多少數給怎麼放都沒事的數code
若是有出現兩次就不合法的數,那麼就先算不存在它的排列,再算存在它一個的排列ip
#include <bits/stdc++.h> #define enter putchar('\n') #define space putchar(' ') #define pii pair<int,int> #define fi first #define se second #define mp make_pair #define MAXN 1000005 #define mo 999999137 #define pb push_back //#define ivorysi using namespace std; typedef long long int64; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) out(x / 10); putchar('0' + x % 10); } const int MOD = 998244353; int fac[4005],inv[4005],invfac[4005],N,K,vis[4005],pw[4005]; int dp[4005][4005]; int mul(int a,int b) { return 1LL * a * b % MOD; } int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int C(int n,int m) { if(n < m) return 0; if(n < 0 || m < 0) return 0; return mul(fac[n],mul(invfac[m],invfac[n - m])); } int fpow(int x,int c) { int res = 1,t = x; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif inv[1] = 1;pw[0] = 1; for(int i = 2 ; i <= 4000 ; ++i) { inv[i] = mul(inv[MOD % i],MOD - MOD / i); } fac[0] = invfac[0] = 1; for(int i = 1 ; i <= 4000 ; ++i) { fac[i] = mul(fac[i - 1],i);invfac[i] = mul(invfac[i - 1],inv[i]); pw[i] = mul(pw[i - 1],2); } read(K);read(N); dp[0][1] = 1; for(int i = 1 ; i <= N ; ++i) dp[i][1] = 2; dp[0][0] = 1; for(int j = 2 ; j <= K ; ++j) { int s = 1; dp[0][j] = 1; for(int i = 1 ; i <= N ; ++i) { dp[i][j] = inc(mul(s,2),dp[i][j - 1]); s = inc(s,dp[i][j - 1]); } } for(int i = 2 ; i <= 2 * K ; ++i) { int cnt = 0,t = 0,rest = 0; memset(vis,0,sizeof(vis)); for(int j = 1 ; j <= K ; ++j) { if(!vis[j] && j != i - j && i - j >= 1 && i - j <= K) {vis[j] = vis[i - j] = 1;++cnt;} } if(i % 2 == 0) ++t; rest = K - cnt * 2 - t; int ans = 0; for(int j = N ; j >= 0 ; --j) { ans = inc(ans,mul(dp[j][cnt],rest ? C(N - j - 1 + rest,rest - 1) : (N - j == 0))); } if(t) { for(int j = N - 1; j >= 0 ; --j) { ans = inc(ans,mul(dp[j][cnt],rest ? C(N - 2 - j + rest,rest - 1) : (N - 1 - j == 0))); } } out(ans);enter; } return 0; }
咱們按照逆操做考慮,容易發現是1-N順序排列
每次交換\(a_{i - 1} < a_{i} < a_{i + 1}\)使得它變成排列p
這樣原始排列每次交換的時候相鄰兩個不會都進行操做,因此排列p若是合法的話必定是
p[i] != i p[i + 1] == i + 1 p[i + 2] != i + 2....這樣的排列get
因此咱們只要對p排列,順序找出區間l,r保證l + 1,l + 3...r - 1是固定不動的
而後找出剩下往左往右的點,保證往左的點是順序的,往右的點是順序的便可string
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #define enter putchar('\n') #define space putchar(' ') #define fi first #define se second #define MAXN 300005 //#define ivorysi #define pii pair<int,int> using namespace std; typedef long long int64; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int N; int p[MAXN],v[MAXN],cnt,id[MAXN],dir[MAXN]; bool vis[MAXN]; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) read(p[i]); int la = 1; while(1) { while(p[la] == la && la <= N) ++la; if(la > N) break; int ed = la; while(1) { if(ed <= N && ((ed - la) & 1) && p[ed] == ed) ++ed; else if(ed <= N && !((ed - la) & 1) && p[ed] != ed) ++ed; else break; } --ed; if(p[ed] == ed) --ed; if(ed == la) {puts("No");return;} cnt = 0; for(int i = la ; i <= ed ; ++i) v[++cnt] = p[i]; sort(v + 1,v + cnt + 1); for(int i = 1 ; i <= cnt ; ++i) { if(v[i] != i + la - 1) {puts("No");return;} } cnt = 0; for(int i = la ; i <= ed ; i += 2) { v[++cnt] = p[i]; id[p[i]] = cnt; } sort(v + 1,v + cnt + 1); for(int i = la ; i <= ed ; i += 2) { int t = lower_bound(v + 1,v + cnt + 1,p[i]) - v; if(t <= id[p[i]]) dir[i] = 0; else dir[i] = 1; } int L = 0,R = 0; for(int i = la ; i <= ed ; i += 2) { if(dir[i] == 0) { if(p[i] < L) {puts("No");return;} L = p[i]; } else { if(p[i] < R) {puts("No");return;} R = p[i]; } } la = ed + 1; } puts("Yes"); } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }