A:显然a*kb*kc*k这样构造能满足
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 2e4 + 5; const int M = 1e6 + 5; const LL Mod = 1e9+7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; char a[3]; int main() { a[0] = 'a',a[1] = 'b',a[2] = 'c'; int ca;ca = read(); while(ca--) { int n,k;n = read(),k = read(); int tot = 0; for(int i = 1;i <= n;++i) { printf("%c",a[tot]); if(i % k == 0) tot = (tot + 1) % 3; } printf(" "); } //system("pause"); return 0; }
B:维护一行前缀和,然后枚举即可
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 2e4 + 5; const int M = 1e6 + 5; const LL Mod = 1e9+7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; string s[505]; int sum[505][505]; int main() { int ca;ca = read(); while(ca--) { memset(sum,0,sizeof(sum)); int n,m;n = read(),m = read(); for(int i = 0;i < n;++i) cin >> s[i]; for(int i = 0;i < n;++i) for(int j = 0;j < m;++j) sum[i][j] = (j == 0 ? 0 : sum[i][j - 1]) + (s[i][j] == '*'); LL ans = 0; for(int i = 0;i < n;++i) { for(int j = 0;j < m;++j) { if(s[i][j] == '*') { ans++; int lex = i + 1,ley = j - 1; int rix = i + 1,riy = j + 1; while(lex < n && rix < n && ley >= 0 && riy < m) { int ma = sum[rix][riy] - (ley == 0 ? 0 : sum[lex][ley - 1]); if(ma < riy - ley + 1) break; lex++,rix++; ley--,riy++; ans++; } } } } printf("%lld ",ans); } //system("pause"); return 0; }
C:容斥思想。
首先,显然是该位置后面都要是全排列,这个位置才有可能到递增全排列。
那么,最后一个满足a[i] != i的位置显然就是这个截断的点,我们考虑容斥所有不可能的概率。
那么可能概率即可得到。
正常来说,这里可以正向递推,每次让其余都无法成立即可。
但是这里的数据对于一个点的概率可能多次出现,且这个贡献每次都看成一个独立的点,所以如果正向推的话去递加这个概率。
就和正确的贡献推得不一样,所以要容斥才行。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 1e6 + 5; const LL Mod = 1e9+7; #define pi acos(-1) #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; int a[N]; double b[N]; bool vis[N]; int main() { int ca;ca = read(); while(ca--) { int n,m;n = read(),m = read(); for(int i = 1;i <= n;++i) b[i] = -1,vis[i] = 0; for(int i = 1;i <= n;++i) a[i] = read(); for(int i = n;i >= 1;--i) { if(i == n && a[i] == i) vis[i] = 1; else if(i != n && a[i] == i && vis[i + 1]) vis[i] = 1; } double ans = 1.0; while(m--) { int x;double t; cin >> x >> t; if(x == n || vis[x + 1]) ans *= (1 - t); } if(vis[1]) printf("1.00000000 "); else { ans = 1 - ans; printf("%.10f ",ans); } } // system("pause"); return 0; } /* 10 5 1 3 2 4 5 6 7 8 9 10 10 0.000138 1 0.000268 5 0.000341 10 0.000223 9 0.000353 */
D:感觉比较简单,稍微看了下就想到了。
显然位置最后都会被分类排好序,那么可以设想到这个不断分解的次数肯定不多,我们把所有情况的值都标记下来即可O(1)询问。
所以分治 + 二分来分解。
#include<bits/stdc++.h> using namespace std; typedef long long LL; typedef pair<int,int> pii; const int N = 1e5 + 5; const int M = 1e6 + 5; const LL Mod = 1e9+7; #define pi acos(-1) #define INF 1e9 + 5 #define dbg(ax) cout << "now this num is " << ax << endl; namespace FASTIO{ inline LL read(){ LL x = 0,f = 1;char c = getchar(); while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();} while(c >= '0' && c <= '9'){x = (x<<1)+(x<<3)+(c^48);c = getchar();} return x*f; } } using namespace FASTIO; int a[N]; LL sum[N]; map<LL,int> mp; int query(int le,int ri,int val) { int L = le,r = ri,ans = le - 1; while(L <= r) { int mid = (L + r) >> 1; if(a[mid] <= val) L = mid + 1,ans = mid; else r = mid - 1; } return ans; } void solve(int L,int r) { int mid = (a[L] + a[r]) / 2; int pos = query(L,r,mid); LL ma1 = sum[pos] - sum[L - 1]; LL ma2 = sum[r] - sum[pos]; mp[ma1] = 1,mp[ma2] = 1; if(a[L] == a[r]) return ; solve(L,pos); solve(pos + 1,r); } int main() { int ca;ca = read(); while(ca--) { mp.clear(); memset(sum,0,sizeof(sum)); int n,q;n = read(),q = read(); for(int i = 1;i <= n;++i) a[i] = read(); sort(a + 1,a + n + 1); for(int i = 1;i <= n;++i) sum[i] = sum[i - 1] + a[i]; solve(1,n); mp[sum[n]] = 1; while(q--) { int x;x = read(); printf("%s ",mp[x] ? "Yes" : "No"); } } // system("pause"); return 0; }
E:
贪心考虑所有情况,然后注意取模来找循环区间。