對於每一個B二分求出幾個A比它小記爲sum
而後對於每一個C就是比它小的B的sum的和c++
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N; int A[MAXN],B[MAXN],C[MAXN]; int64 sum[MAXN]; void Solve() { read(N); for(int i = 1 ; i <= N ; ++i) read(A[i]); for(int i = 1 ; i <= N ; ++i) read(B[i]); for(int i = 1 ; i <= N ; ++i) read(C[i]); sort(A + 1,A + N + 1);sort(B + 1,B + N + 1);sort(C + 1,C + N + 1); for(int i = 1 ; i <= N ; ++i) { sum[i] = lower_bound(A + 1, A + N + 1, B[i]) - A - 1; sum[i] += sum[i - 1]; } int64 ans = 0; for(int i = 1 ; i <= N ; ++i) { ans += sum[lower_bound(B + 1,B + N + 1,C[i]) - B - 1]; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
一開始記了一個位數,結果開到了2000多位都WA
其實發現答案不會超過5 * 9
直接設\(dp[i][j]\)爲如今答案是\(i\),\(%K\)意義下是\(j\)
每次轉移日後加一位就行,就是若是加了一位\(h\),第二維是\((10j + h) % K\)spa
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int K; bool dp[55][100005]; queue<int> Q; void Solve() { read(K); for(int i = 1 ; i <= 9 ; ++i) dp[i][i % K] = 1; for(int i = 1 ; i <= 50 ; ++i) { for(int a = 0 ; a < K ; ++a) { if(dp[i][a]) Q.push(a); } while(!Q.empty()) { int v = Q.front();Q.pop(); if(!dp[i][v * 10 % K]) { dp[i][v * 10 % K] = 1; Q.push(v * 10 % K); } } for(int a = 0 ; a < K ; ++a) { if(!dp[i][a]) continue; for(int j = 1 ; j <= 9 ; ++j) { if(i + j > 50) break; int h = (a * 10 + j) % K; dp[i + j][h] = 1; } } } for(int i = 1 ; i <= 50 ; ++i) { if(dp[i][0]) { out(i);enter;return; } } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
若是K是偶數的話,答案是K / 2,K,K,K,K.....
若是K是奇數構造一個數列
K / 2 +1,K / 2 + 1,K / 2 + 1,K / 2 + 1.....
長度爲N
發現一個序列
\(a_i\)映射到\(K - a_i + 1\)若是\(a_i\)不是構造出的這個序列的一個前綴,那麼確定這兩個序列中,一個在這個序列前,一個在這個序列後
因此這個序列的排名是\((S + N) / 2\)
往前倒退\(N / 2\)個便可code
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define pdi pair<db,int> #define mp make_pair #define pb push_back #define enter putchar('\n') #define space putchar(' ') #define eps 1e-8 #define mo 974711 #define MAXN 300005 //#define ivorysi using namespace std; typedef long long int64; typedef double db; 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) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,K; int a[MAXN]; void Solve() { read(K);read(N); if(K % 2 == 0) { out(K / 2);space; for(int i = 2 ; i <= N ; ++i) { out(K);space; } enter; } else { for(int i = 1 ; i <= N ; ++i) a[i] = (K + 1) / 2; int t = N / 2; int p = N; while(t--) { --a[p]; if(a[p] != 0) { for(int i = p + 1 ; i <= N ; i++) a[i] = K; p = N; } if(a[p] == 0) --p; } for(int i = 1 ; i <= N ; ++i) { if(a[i] != 0) { out(a[i]);space; } } enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }
就是考慮兩個多項式,它們互相消,確定會消成0,這個消成0以前的,就是他們的gcd
全部的數確定都是這個gcd的倍數
因此咱們設gcd長度爲a,x長度爲b
這個數前\(b - a +1\)隨便填,後面的位數能夠惟一肯定,因此答案就是\(x\)的前\(b - a +1\)位二進制構成的數+1
可是有個特殊的,就是若是前面剛好等於\(x\)的狀況,可能後面肯定好的數就超過了x,這個特判一下減掉就好ip
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 #define eps 1e-10 //#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; vector<int> num[7],x,g,t; int N; char s[4005]; vector<int> gcd(vector<int> a,vector<int> b) { if(a.size() < b.size()) swap(a,b); if(b.size() == 1 && b[0] == 0) return a; vector<int> d(a.size()); int t = a.size() - 1; for(int i = b.size() - 1 ; i >= 0 ; --i) { d[t] = a[t] ^ b[i]; --t; } for(int i = t ; i >= 0 ; --i) d[i] = a[i]; while(d.size() > 1) { if(d.back() == 0) d.pop_back(); else break; } return gcd(b,d); } void Init() { read(N); scanf("%s",s + 1); int len = strlen(s + 1); for(int i = len ; i >= 1 ; --i) { x.pb(s[i] - '0'); } for(int i = 1 ; i <= N ; ++i) { scanf("%s",s + 1); len = strlen(s + 1); for(int j = len ; j >= 1 ; --j) num[i].pb(s[j] - '0'); } g = num[1]; for(int i = 2 ; i <= N ; ++i) g = gcd(g,num[i]); } void Solve() { t = x; if(g.size() > x.size()) {out(1);enter;return;} int l = x.size() - g.size() + 1; int d = x.size() - 1; int ans = 0; for(int i = 0 ; i < l ; ++i) { ans = (1LL * ans * 2 + x[d - i]) % MOD; } ans = (ans + 1) % MOD; for(int i = l ; i < x.size() ; ++i) t[d - i] = 0; for(int i = 0 ; i < l ; ++i) { if(t[d - i] == 1) { int k = g.size() - 1; for(int j = 0 ; j < g.size() ; ++j) { t[d - i - j] = t[d - i - j] ^ g[k - j]; } } } for(int i = l ; i < x.size() ; ++i) { if(t[d - i] != x[d - i]) { if(t[d - i] > x[d - i]) ans = (ans + MOD - 1) % MOD; break; } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }