A. 3:20:22(-1) solved by hl
WA点:三年竞赛一场空,不开LL见祖宗
由题意化为 要求左右两回文串都是奇数长度且相互覆盖对方的回文串中点。
用Manacher预处理之后 对于每个回文串x产生的后效性,在经过中点i的时候加入树状数组,经过终点i + Mp[i] + 1的移出树状数组
对于每个中点为i回文串作为后边那个产生的贡献,将所有中点位于 i + Mp[i] - 1 到 i - 1的回文串计出贡献
树状数组负责维护后缀和
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x) #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",x) #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int 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 * 10 + c - '0';c = getchar();}return x*f;} const double PI = acos(-1.0); const double eps = 1e-9; const int maxn = 5e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char str[maxn]; char Ma[maxn << 1]; int Mp[maxn <<1]; void Manacher(char s[],int len){ int l = 0; Ma[l++] = '$'; Ma[l++] = '#'; for(int i = 0 ; i < len; i ++){ Ma[l++] = s[i]; Ma[l++] = '#'; } Ma[l] = 0; int mx = 0,id = 0; for(int i = 0 ; i < l; i ++){ Mp[i] = mx > i?min(Mp[2 * id - i],mx - i):1; while(Ma[i + Mp[i]] == Ma[i - Mp[i]]) Mp[i]++; if(i + Mp[i] > mx){ mx = i + Mp[i]; id = i; } } } vector<int>Q[maxn * 2]; LL tree[maxn * 2],l; void add(int p,int x){ for(;p > 0; p -= p & -p) tree[p] += x; } LL getsum(int p){ if(!p) p ++; LL ans = 0; for(;p <= 2 * l + 2; p += p & -p) ans += tree[p]; return ans; } int main(){ int T; Sca(T); while(T--){ scanf("%s",str); l = strlen(str); Manacher(str,l); LL ans = 0; for(int i = 0 ; i < 2 * l + 2; i ++) Q[i].clear(); for(int i = 0 ; i <= 2 * l + 2; i ++) tree[i] = 0; for(int i = 2; i < 2 * l + 2; i += 2){ Mp[i]--; ans += getsum(i - Mp[i] + 1); if(Mp[i] > 1){ Q[i + Mp[i] - 1].pb(i); add(i,1); } for(int j = 0 ; j < Q[i].size(); j ++){ add(Q[i][j],-1); } Q[i].clear(); } Prl(ans); } return 0; } /* */
B.3:44:10(-1) solved by hl
二分最终答案,将原序列大于等于二分值的视为1,剩下的视为0
那么满足条件的区间的个数就是所有序列中区间和 >= K的区间的个数
线性时间求解完之后判断是否大于M
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x) #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",x) #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int 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 * 10 + c - '0';c = getchar();}return x*f;} const double PI = acos(-1.0); const double eps = 1e-9; const int maxn = 1e5 +10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N; LL M,K; int a[maxn],b[maxn]; int pre[maxn],id[maxn]; bool check(int x){ for(int i = 1; i <= N ; i ++) b[i] = (a[i] >= x); LL ans = 0; for(int i = 1; i <= N ; i ++){ pre[i] = pre[i - 1] + b[i]; if(b[i]) id[pre[i]] = i; if(pre[i] >= K) ans += id[pre[i] - K + 1]; } return ans >= M; } int solve(){ int l = 0,r = INF; int ans = INF; while(l <= r){ int m = l + r >> 1; if(check(m)){ ans = m; l = m + 1; }else{ r = m - 1; } } return ans; } int main(){ int T; Sca(T); while(T--){ scanf("%d%lld%lld",&N,&K,&M); for(int i = 1; i <= N ; i ++) Sca(a[i]); Pri(solve()); } return 0; }
F.0:11:37 solved by hl
下标为奇数的构造为1,2,3,4,5 ... x
下标为偶数的构造为x + 1,x + 2.. N
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x) #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",x) #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int 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 * 10 + c - '0';c = getchar();}return x*f;} const double PI = acos(-1.0); const double eps = 1e-9; const int maxn = 1e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int a[maxn]; int main(){ int T; Sca(T); while(T--){ int cnt = 0; Sca(N); for(int i = 1; i <= N; i += 2) a[i] = ++cnt; for(int i = 2; i <= N ; i += 2) a[i] = ++ cnt; for(int i = 1; i <= N ; i ++){ printf("%d ",a[i]); } puts(""); } return 0; }
H.3:09:34(-5) solved by gbs
很显然最终状态的最大公因数只要考虑质数就够了
预处理出1e5以下的所有素数,枚举所有素数然后贪心check
#include <iostream> #include<stack> #include<math.h> #include<stdlib.h> #include<string.h> #include<string> #include<ctime> #include<complex> #include<stdio.h> #include<algorithm> #include<map> #include<queue> #include<deque> using namespace std; typedef long long LL; const int mod =1e9+7; //10*n const int maxn =1e5+35; int n; bool if_p[maxn+15]; int p_list[maxn/2+15]; int an[maxn]; LL sum ; int p_num =0; LL fen_list[500]; int fen_num; LL fin_ans; void pre() { memset(if_p,true,sizeof(if_p)); for (int i=2; i<maxn; i++) { if (if_p[i]) { p_list[p_num++] = i; //cout<<i<<endl; for (int j = i<<1; j<maxn; j+= i) { if_p[j] =false; } } } } void fen(LL n) { fen_num =0; for (int i=0; i<p_num; i++) { if (p_list[i]>n) break ; if(n%p_list[i] == 0) { fen_list[fen_num++] = p_list[i]; while(n%p_list[i] == 0) n/=p_list[i]; } } if (n> 1) { fen_list[fen_num++] =n; } } int remain[maxn+15]; void judge(LL a) { LL now_time = 0; LL best_time =0; int h1; if (a<= 100000) { memset(remain,0,sizeof(int)*(a+4)); for (int i=0; i<n; i++) { h1= an[i]%a; if (h1==0) continue; remain[h1]++; best_time += min(0LL+h1,a-h1); if (best_time>=(fin_ans<<1)) return ; } } else { sort(an,an+n); int time2 = sum/a; for (int i=0; i<n-time2; i++) { now_time += an[i]; } fin_ans = min(fin_ans,now_time); return ; } if (a == 2) { fin_ans = min(fin_ans,0LL+remain[1]/2); return ; } int lef = 1; int rif = a-1;//a-1 now_time += 1LL* (a-rif)*remain[rif] + 1LL * lef*remain[lef]; LL now_c = (a-rif)*remain[rif] - 1LL * lef*remain[lef]; while(lef!= rif-1) { if (now_c<0) { rif--; now_c += (a-rif)*remain[rif]; now_time += (a-rif)*remain[rif]; } else { lef++; now_c -= 1LL*lef*remain[lef]; now_time += 1LL*lef*remain[lef]; } } LL time1 ; time1 = abs(now_c)/a; if (now_c >0) { now_time+= time1 * (2*rif-a); } else { now_time+= time1 * (a-lef-lef); } fin_ans = min(fin_ans,now_time/2); } /*void judge(LL a) { LL now_time = 0; LL best_time =0; int h1; deque<LL>dqu; if (a<= 100000) { memset(remain,0,sizeof(int)*(a+4)); for (int i=0; i<n; i++) { h1= an[i]%a; if (h1==0) continue; remain[h1]++; best_time += min(0LL+h1,a-h1); if (best_time>=fin_ans<<1) return ; } if (a == 2) { fin_ans = min(fin_ans,0LL+remain[1]/2); return ; } for (int i=1; i<a; i++) { while(remain[i]--) { dqu.push_back(i); } } } else { sort(an,an+n); for (int i=0; i<n; i++) { dqu.push_back(an[i]); best_time +=min(0LL+an[i],a-an[i]); if (best_time>=fin_ans<<1) return ; } } LL t1,t2,t3; while(!dqu.empty()) { t1 = dqu.front(); t2 = dqu.back(); dqu.pop_back(); dqu.pop_front(); t3 = min(t1,a-t2); t1-=t3; t2+=t3; now_time += t3; if (now_time >=fin_ans) return ; if (t1!= 0) dqu.push_front(t1); if (t2 != a) dqu.push_back(t2); } fin_ans = min(fin_ans,now_time); }*/ int main() { pre(); int t; cin >>t; while(t--) { cin >>n; sum =0; for (int i=0; i<n; i++) { scanf("%d",&an[i]); //an[i] = 100000; sum += an[i]; } fin_ans = 1e17; fen(sum); if (sum == 0) { cout<<0<<endl; continue; } for (int i =0; i<fen_num; i++) { //cout<<fen_list[i]<<"D"<<endl; //cout<<sum<<"S"<<fen_list[i]<<endl; judge(fen_list[i]); } cout<<fin_ans<<endl; } return 0; } /* 111 5111111 11111116 12133215 251111111 111 5 15 5 25 5 14 5 25 5 13 5 25 5 12 5 25 3 14 14 5 5 14 14 5 5 */
J. 5:10:01 solved by zcz
HL:他弄了一个很复杂的公式给我敲,至于怎么整出来的,咱也不知道,咱也不敢问
#include <map> #include <set> #include <ctime> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <bitset> #include <cstdio> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> #include <functional> using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++) #define _For(i, x, y) for(int i=x;i>=y;i--) #define Mem(f, x) memset(f,x,sizeof(f)) #define Sca(x) scanf("%d", &x) #define Sca2(x,y) scanf("%d%d",&x,&y) #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define Scl(x) scanf("%lld",&x) #define Pri(x) printf("%d ", x) #define Prl(x) printf("%lld ",x) #define CLR(u) for(int i=0;i<=N;i++)u[i].clear(); #define LL long long #define ULL unsigned long long #define mp make_pair #define PII pair<int,int> #define PIL pair<int,long long> #define PLL pair<long long,long long> #define pb push_back #define fi first #define se second typedef vector<int> VI; int read(){int 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 * 10 + c - '0';c = getchar();}return x*f;} const double PI = acos(-1.0); const double eps = 1e-9; const int maxn = 110; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; LL quick_power(LL a,LL b){ LL ans = 1; while(b){ if(b & 1) ans = ans * a % mod; b >>= 1; a = a * a % mod; } return ans; } LL inv(LL a){ return quick_power(a,mod - 2); } LL x[10],y[10]; LL fac(LL v){ x[1] = 2; y[1] = 2; x[2] = 3; y[2] = 8; x[3] = 4; y[3] = 20; x[4] = 5; y[4] = 40; x[5] = 6; y[5] = 70; LL ans = 0; for(int i = 1; i <= 5; i ++){ LL sum = 1; for(int j = 1; j <= 5; j ++){ if(i != j) sum = sum * (x[i] + mod - x[j]) % mod; } sum = inv(sum); sum = sum * y[i] % mod; for(int j = 1; j <= 5; j ++){ if(i != j) sum = sum * (v - x[j] + mod) % mod; } ans = (ans + sum) % mod; } return ans; } LL fac2(LL v){ x[1] = 1; y[1] = 6; x[2] = 2; y[2] = 30; x[3] = 3; y[3] = 90; x[4] = 4; y[4] = 210; x[5] = 5; y[5] = 420; LL ans = 0; for(int i = 1; i <= 5; i ++){ LL sum = 1; for(int j = 1; j <= 5; j ++){ if(i != j) sum = sum * (x[i] + mod - x[j]) % mod; } sum = inv(sum); sum = sum * y[i] % mod; for(int j = 1; j <= 5; j ++){ if(i != j) sum = sum * (v - x[j] + mod) % mod; } ans = (ans + sum) % mod; } return ans; } inline LL mul(LL a,LL b){ return a % mod * b % mod; } inline LL add(LL a,LL b){ return ((a + b) % mod + mod) % mod; } LL S3(LL x){ return x * (x + 1) % mod * x % mod * (x + 1) % mod * inv(2) % mod * inv(2) % mod; } LL S1(LL x){ return (x + 1) * x % mod * inv(2) % mod; } LL S2(LL x){ return mul(mul(mul(x,add(x,1)),add(2 * x % mod,1)),inv(6)); } int main(){ int T; Sca(T); LL inv2 = inv(2); while(T--) { LL a,b; scanf("%lld %lld",&a,&b); long long ans; LL n = a; if(b==1) { ans = mul(inv2,(add(add(-S3(n),-S2(n)),mul(add(S1(n),S2(n)),n)))); ans = mul(ans,inv(add(mul(S1(n),n),-S2(n)))); } else { ans= mul(mul(inv2,add(S3(n),-S1(n))),inv(add(S2(n),-S1(n)))); } printf("%lld ",ans); } return 0; }
L. unsolved by hl
赛后补题 HDU6241 17CCPC哈尔滨L
M.2:56:06(-14) solved by zcz
每次随机找3个点,求出他们的圆心去check是否为最终答案
因为至少一半的点在最终答案的圆上,每次就有1 / 8的概率中奖
因为每次都直接随机点,显然出题人不能构造出让我们TLE的数据
#include<iostream> #include<cstring> #include<cstdio> #include<ctime> #include<cstdlib> #include<cmath> using namespace std; int random(int n) { return (long long)rand()*rand()%n; } struct Point { double x,y; Point(double x0=0,double y0=0) : x(x0) , y(y0) { } friend Point operator-(const Point &a,const Point &b) { return Point(a.x-b.x,a.y-b.y); } friend Point operator+(const Point &a,const Point &b) { return Point(a.x+b.x,a.y+b.y); } friend Point operator*(const Point &a,double b) { return Point(a.x*b,a.y*b); } }; double Cross(Point a,Point b) { return a.x*b.y-b.x*a.y; } Point getLineIntersection(const Point &P,const Point &v,const Point &Q,const Point &w) { Point u=P-Q; double t=Cross(w,u)/Cross(v,w); return P+v*t; } Point p[100005]; int n; const double eps=1e-9; int dcmp(double x) { return x>eps||x<-eps; } Point Get(Point a,Point b,Point c) { Point p1,p2,v1,v2; p1.x=(a.x+b.x)/2; p1.y=(a.y+b.y)/2; p2.x=(a.x+c.x)/2; p2.y=(a.y+c.y)/2; v1.x=a.y-b.y; v1.y=b.x-a.x; v2.x=a.y-c.y; v2.y=c.x-a.x; if(dcmp(v1.x*v2.y-v2.x*v1.y)==0) return Point(0,0); return getLineIntersection(p1,v1,p2,v2); } double dis(Point a,Point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } bool judge(Point T,double R) { int cnt=0; for(int i=0;i<n;i++) { if(dcmp(sqrt(dis(T,p[i]))-sqrt(R))==0) { cnt++; } } return cnt>=(n+1)/2; } void solve() { int t1,t2,t3; if(n<=4) { if(n==1) { double tt=1; printf("%lf %lf %lf ",p[0].x+1,p[0].y,tt); } else { printf("%.10lf %.10lf %.10lf ",(p[0].x+p[1].x)/2,(p[0].y+p[1].y)/2,sqrt(dis(p[0],p[1]))/2); } return ; } while(1) { t1=random(n); do { t2=random(n); } while(t2==t1); do { t3=random(n); } while(t3==t2||t3==t1); Point T=Get(p[t1],p[t2],p[t3]); double R=dis(p[t1],T); double MAX=1e9; if(sqrt(R)>=MAX||T.x>=MAX||T.x<=-MAX||T.y>=MAX||T.y<=-MAX) continue; if(judge(T,R)) { printf("%.10lf %.10lf %.10lf ",T.x,T.y,sqrt(R)); break; } } } int main() { srand((unsigned)time(NULL)); int T; cin>>T; while(T--) { cin>>n; for(int i=0;i<n;i++) { scanf("%lf%lf",&p[i].x,&p[i].y); } solve(); } return 0; }