The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803
The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803
- 前言
- 题目
- A. August
- B. Bills of Paradise
- C. Cornelia Street
- D. Death by Thousand Cuts
- F. False God
- G. Goodbye
- H. Hate That You Know Me
- K. Keeping A Secret
- L. Let's Get Married
- 总结
前言
刚和队友组队,第一次一起vp,也为几天后的比赛做准备
题目
A. August
https://codeforces.com/gym/102803/problem/A
给定四条曲线,有两个参数,求包围的面积,其中有两条是圆,有两条是反三角函数(下面是样例的图)
圆面积直接求。反三角函数转成三角函数直接积分即可
队友代码:
#include<bits/stdc++.h>
#define N
using namespace std;
bool cur1;
int n;
inline void Rd(int &res){char c;res=0;while(c=getchar(),c<48);do res=(res<<3)+(res<<1)+(c^48);while(c=getchar(),c>47);return;
}
bool cur2;
int main(){// printf("%lf MB\n",(&cur2-&cur1)/1024.0/1024);
// freopen("data.txt","r",stdin);int T;Rd(T);while(T--){int a,b;Rd(a);Rd(b);double pi=acos(-1);printf("%lf\n",4.0*a*b+pi*a*a);}return 0;
}
B. Bills of Paradise
https://codeforces.com/gym/102803/problem/B
一眼数据结构,直接交给队友了
队友代码:
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
bool cur1;
int n,q;
unsigned long long k1, k2;
long long a[N];
inline unsigned long long xorShift128Plus() {unsigned long long k3 = k1, k4 = k2;k1 = k4;k3 ^= k3 << 23;k2 = k3 ^ k4 ^ (k3 >> 17) ^ (k4 >> 26);return k2 + k4;
}
inline void Rd(int &res){char c;res=0;while(c=getchar(),c<48);do res=(res<<3)+(res<<1)+(c^48);while(c=getchar(),c>47);return;
}
inline int get1(long long x){int l=1,r=n,res=-1;while(l<=r){int mid=(l+r)>>1;if(a[mid]>=x)res=mid,r=mid-1;else l=mid+1;}return res;
}
inline int get2(long long x){int l=1,r=n,res=-1;while(l<=r){int mid=(l+r)>>1;if(a[mid]<=x)res=mid,l=mid+1;else r=mid-1;}return res;
}
struct YDtree{#define ls p<<1#define rs p<<1|1bool hv[N<<2],flag[N<<2];long long sum[N<<2],len[N<<2];inline void up(int p){sum[p]=sum[ls]+sum[rs];hv[p]=hv[ls]|hv[rs];}inline void down(int p){if(flag[p]){flag[ls]=flag[rs]=1;hv[ls]=hv[rs]=1;sum[ls]=len[ls];sum[rs]=len[rs];flag[p]=0;}}void build(int l,int r,int p){if(l==r){sum[p]=len[p]=a[l];hv[p]=1;return;}int mid=(l+r)>>1;build(l,mid,ls);build(mid+1,r,rs);len[p]=len[ls]+len[rs];up(p);}long long quiry1(int l,int r,int L,int R,int p){if(!hv[p])return -1;if(l==r)return a[l];down(p);int mid=(l+r)>>1;if(!hv[ls]||mid<L)return quiry1(mid+1,r,L,R,rs);long long h=quiry1(l,mid,L,R,ls);if(h==-1){if(mid<R)return quiry1(mid+1,r,L,R,rs);return -1;}return h;}bool update2(int l,int r,int L,int R,int p){if(!hv[p])return false;if(l==r){sum[p]=0;hv[p]=0;return true;}down(p);bool res;int mid=(l+r)>>1;if(!hv[ls]||mid<L)res=update2(mid+1,r,L,R,rs);else{res=update2(l,mid,L,R,ls);if(!res){if(mid<R)res=update2(mid+1,r,L,R,rs);}}up(p);return res;}long long quiry3(int l,int r,int L,int R,int p){if(L<=l&&r<=R)return sum[p];down(p);int mid=(l+r)>>1;long long res=0;if(mid>=L)res=quiry3(l,mid,L,R,ls);if(mid<R)res+=quiry3(mid+1,r,L,R,rs);return res;}void update4(int l,int r,int L,int R,int p){if(L<=l&&r<=R){flag[p]=1;sum[p]=len[p];hv[p]=1;return;}down(p);int mid=(l+r)>>1;if(mid>=L)update4(l,mid,L,R,ls);if(mid<R)update4(mid+1,r,L,R,rs);up(p);}
}YD;
bool cur2;
int main(){// printf("%lf MB\n",(&cur2-&cur1)/1024.0/1024);
// freopen("data.txt","r",stdin);scanf("%d %llu %llu", &n, &k1, &k2);for (int i = 1; i <= n; i++) a[i] = xorShift128Plus() % 999999999999 + 1;sort(a+1,a+n+1);YD.build(1,n,1);Rd(q);for(int i=1;i<=q;i++){char str[3];long long x;scanf("%s %lld",str,&x);if(str[0]=='F'){int h=get1(x);if(h==-1)puts("1000000000000");else{long long res=YD.quiry1(1,n,h,n,1);if(res==-1)puts("1000000000000");else printf("%lld\n",res);}}else if(str[0]=='D'){int h=get1(x);if(h==-1)continue;YD.update2(1,n,h,n,1);}else if(str[0]=='C'){int h=get2(x);if(h==-1)puts("0");else printf("%lld\n",YD.quiry3(1,n,1,h,1));}else{int h=get2(x);if(h==-1)continue;YD.update4(1,n,1,h,1);}}return 0;
}
C. Cornelia Street
https://codeforces.com/gym/102803/problem/C
给定一个字符串 S(∣S∣≤8×105)S(|S|\le8\times 10^5)S(∣S∣≤8×105),找到两个等长的串 AAA 和 BBB, 使得 S=AA…ABB…BAA…AaS=AA\dots ABB\dots BAA\dots AaS=AA…ABB…BAA…Aa,其中 aaa 是 AAA 的一个前缀(可以为空),最小化 ∣A∣|A|∣A∣
枚举 ∣A∣|A|∣A∣,找到第一个不匹配的位置,即为 BBB,同样的操作找到连续 BBB 串的结尾,后面判断是否全为 AAA 。判断相等用 hashhashhash 即可,复杂度 O(nlogn)O(n\log n)O(nlogn), logn\log nlogn 是调和级数
代码:
#include<bits/stdc++.h>
/*
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
//*/
using namespace std;
typedef long long ll;
typedef double db;
const int N=1000010,M=1000010,P=1e9+7;
const int p1=1e9+9,p2=998244353;
const int inf=0x3f3f3f3f;
const int INF=0xcfcfcfcf;
const db eps=1e-9,pi=2*asin(1);
template<typename tn> void read(tn &n);
template<typename tn1,typename tn2> bool cmax(tn1 &x,tn2 y) { return x<y?x=y,true:false; }
template<typename tn1,typename tn2> bool cmin(tn1 &x,tn2 y) { return x>y?x=y,true:false; }
#define mp(x,y) make_pair(x,y)
#define pii pair<int,int>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pll pair<ll,ll>
int ADD(int x,int y,int p=P) { return x+y>=p?x+y-p:x+y; }
int MINUS(int x,int y,int p=P) { return x-y<0?x-y+p:x-y; }
#define plus(a,b) a=ADD(a,b)
#define minus(a,b) a=MINUS(a,b)
#define mul(a,b) a=1ll*(a)*(b)%P
#define mem(a,b) memset(a,b,sizeof(a))int BASE=129;
int n;
int h1[N],h2[N];
int m1[N],m2[N];
char s[N];void init()
{m1[0]=m2[0]=1;for(int i=1;i<=n;i++){int ch=s[i]+1;h1[i]=(1ll*h1[i-1]*BASE+ch)%p1;h2[i]=(1ll*h2[i-1]*BASE+ch)%p2;m1[i]=1ll*m1[i-1]*BASE%p1;m2[i]=1ll*m2[i-1]*BASE%p2;// cerr<<h1[i]<<" ";}// cerr<<"\n";
}
pii get(int l,int r)
{return mp(((h1[r]-1ll*h1[l-1]*m1[r-l+1])%p1+p1)%p1,((h2[r]-1ll*h2[l-1]*m2[r-l+1])%p2+p2)%p2);
}template<typename tn> void read(tn &n)
{tn s=0,flag=1;char ch=getchar();for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=-1;for(;'0'<=ch&&ch<='9';ch=getchar()) s=s*10+ch-'0';if(ch=='.'){ch=getchar();tn r=0,R=1;for(;'0'<=ch&&ch<='9';ch=getchar()) r=r*10+ch-'0',R*=10;s+=r/R;}n=s*flag;
}int main()
{scanf("%s",s+1);// cerr<<s+1<<"\n";n=strlen(s+1);init();int stb;for(int i=1;i<=n;i++){// cerr<<i<<": \n";pii a,b;a=get(1,i);int p=i+1;while(p+i-1<=n&&get(p,p+i-1)==a) p+=i;// cerr<<a.first<<" "<<a.second<<" "<<get(p,p+i-1).first<<" "<<get(p,p+i-1).second<<"\n";// cerr<<p<<"\n";if(p+i-1>n&&get(p,n)==get(1,n-p+1)){for(int j=1;j<=i;j++) putchar(s[j]);putchar(' ');for(int j=p-i;j<=p-1;j++) putchar(s[j]);putchar('\n');return 0;}b=get(p,p+i-1),stb=p;// cerr<<p<<" "<<stb<<"\n";while(p+i-1<=n&&get(p,p+i-1)==b) p+=i;// cerr<<b.first<<" "<<b.second<<" "<<get(p,p+i-1).first<<" "<<get(p,p+i-1).second<<"\n";// cerr<<p<<"\n";while(p+i-1<=n&&get(p,p+i-1)==a) p+=i;if(get(p,n)==get(1,n-p+1)){for(int j=1;j<=i;j++) putchar(s[j]);putchar(' ');for(int j=stb;j<=stb+i-1;j++) putchar(s[j]);putchar('\n');return 0;}// cerr<<"\n";}return 0;
}
D. Death by Thousand Cuts
https://codeforces.com/gym/102803/problem/D
给一个正方体和一个法向量确定的平面,求平面与长方体的棱的交点数量为3/4/5/6个的概率
就一个大讨论,分界点一定是长方体的顶点位于平面内的情况(队友nb!!!)
队友代码:
#include <algorithm>
#include <cstdio>
#include <vector>long long gcd(long long a, long long b) {return b ? gcd(b, a % b) : a;
}const int P = int(1e9) + 7;long long pow(long long a, long long b) {long long r = 1;while (b) {if (b & 1) r = r * a % P;b >>= 1;a = a * a % P;}return r;
}long long int_inv(long long x) {return pow(x, P - 2);
}/* a/b */
struct num {long long a, b;num(): a(0), b(1) {}num(long long t): a(t), b(1) {}num(long long a, long long b): a(a), b(b) {simp();}void read() {long long t;scanf("%lld", &t);*this = num(t);}long long print() {long long q = a, p = b;return 1ll * q * int_inv(p) % P;}void dump() {printf("%lld/%lld ", a, b);}void simp() {if (b < 0) {a = -a;b = -b;}long long g = gcd(a, b);a /= g;b /= g;}num operator-() {return num(-a, b);}num inv() {return num(b, a);}friend num operator+(num x, num y) {return num(x.a * y.b + x.b * y.a,x.b * y.b);}friend num operator-(num x, num y) {return x + -y;}friend num operator*(num x, num y) {return num(x.a * y.a,x.b * y.b);}friend num operator/(num x, num y) {return x * y.inv();}friend bool operator==(num x, num y) {return x.a == y.a && x.b == y.b;}friend bool operator<(num x, num y) {num z = x - y;if (z.a == 0) return false;return (z.a < 0) ^ (z.b < 0);}friend bool operator<=(num x, num y) {return x < y || x == y;}bool in_0_1() {return a >= 0 && a <= b;}
};int T;
num a, b, c, A, B, C;num _; // zeronum ans[10]; // ans[3..6];std::vector<num> v;num solve_d(num x, num y, num z) {return -(A * x + B * y + C * z);
}// int is_cross(num D, num x0, num y0, num z0, num dx, num dy, num dz) {// // x = dx*t + x0 ...// // A * (dx*t + x0) + ... + D == 0// // num t = -(
// // (D + A*x0 + B*y0 + C*z0) / (A * dx + B * dy + C * dz)
// // );// return (-((D + A*x0 + B*y0 + C*z0) / (A * dx + B * dy + C * dz))).in_0_1();
// }#define is_cross(D, x0, y0, z0, dx, dy, dz) ((-((D + A*x0 + B*y0 + C*z0) / (A * dx + B * dy + C * dz))).in_0_1())int main() {scanf("%d", &T);while (T--) {a.read();b.read();c.read();A.read();B.read();C.read();v.clear();v.push_back(solve_d(_, _, _));v.push_back(solve_d(_, _, c));v.push_back(solve_d(_, b, _));v.push_back(solve_d(_, b, c));v.push_back(solve_d(a, _, _));v.push_back(solve_d(a, _, c));v.push_back(solve_d(a, b, _));v.push_back(solve_d(a, b, c));std::sort(v.begin(), v.end());// for (auto &z : v) {// z.dump();// printf("\n");// }for (int i = 3; i <= 6; i++) {ans[i] = num(0);}num minD = v[0], maxD = v[7];for (int i = 0; i <= 6; i++) {int j = i + 1;if (v[i] == v[j]) continue;num D = (v[i] + v[j]) / num(2);int cross = 0;cross += is_cross(D, _, _, _, a, _, _);cross += is_cross(D, _, _, _, _, b, _);cross += is_cross(D, a, _, _, _, b, _);cross += is_cross(D, _, b, _, a, _, _);cross += is_cross(D, _, _, _, _, _, c);cross += is_cross(D, a, _, _, _, _, c);cross += is_cross(D, _, b, _, _, _, c);cross += is_cross(D, a, b, _, _, _, c);cross += is_cross(D, _, _, c, a, _, _);cross += is_cross(D, _, _, c, _, b, _);cross += is_cross(D, a, _, c, _, b, _);cross += is_cross(D, _, b, c, a, _, _);// printf("D=[");// v[i].dump();// printf("..");// v[j].dump();// printf("] (avg=");// D.dump();// printf(") cross=%d\n", cross);ans[cross] = ans[cross] + (v[j] - v[i]) / (maxD - minD);}printf("%lld %lld %lld %lld\n", ans[3].print(), ans[4].print(), ans[5].print(), ans[6].print());}
}
F. False God
https://codeforces.com/gym/102803/problem/F
回合制游戏,每回合你先动。对面有 n(n≤1000)n(n\le 1000)n(n≤1000) 颗棋子,每回合都会朝前(你)移动一步。你有一颗棋子,每回合可以向前/后/左/右/左前/右前移动一步。求你最多可以吃掉几颗对面的棋子
首先先简化操作。我们发现在正常情况下后退是没用的,因为你不会走到一颗棋子的后面,不然你上一回合就已经把它吃掉了(除非初始情况,一开始判断掉),这样你就不会后退了。
然后可以发现,我们一定是优先横向移动棋子,因为对方棋子的相对位置是不变的,所以我们没必要向前主动地去吃棋子,等对面送上来就行了。
这样就有一个问题,我们每回合必须得移动棋子,不能停在原地,这有点难受。我们可以花两回合停在原地,即先左再右,想要做到一回合不动还是不行,但我们可以替换掉原来的横向移动操作,以向左为例,我们可以先向左前再向后,这样原本一步向左变成了两步向左,实现了一步停留,向前、向右同理。
最后,按照上述的结论,越靠前的棋子越先被吃, dpdpdp 即可。复杂度 O(n2)O(n^2)O(n2)
队友代码:
#include <algorithm>
#include <cstdio>
#include <cstring>#define REP(i, n) for (int i = 0; i < n; i++)#define pii std::pair<int, int>
#define xx first
#define yy secondconst int N = 1003;int T, xx0, yy0, n;
pii p[N];int f[N];int cmp(pii &a, pii &b) {if (a.yy != b.yy) return b.yy > a.yy;return b.xx > a.xx;
}int main() {scanf("%d", &T);while (T--) {memset(f, 0x87, sizeof f);scanf("%d%d%d", &xx0, &yy0, &n);int tag = 0;REP(i, n) {scanf("%d%d", &p[i].xx, &p[i].yy);tag |= p[i].xx == xx0 && p[i].yy == yy0-1;}if (!tag) {p[n].xx = xx0;p[n].yy = yy0-1;n++;}std::sort(p, p+n, cmp);int ans = 0;pii *pp = std::find(p, p + n, pii{xx0, yy0-1});if (tag) {f[pp-p]=1;// printf("%d,%d :: 1\n", xx0, yy0-1);} else {f[pp-p]=0;// printf("%d,%d :: 0\n", xx0, yy0-1);}for (int i = 0; i < n; i++) {for (int j = 0; j < i; j++) {if (p[j].yy > p[i].yy) continue;if (p[j].yy == p[i].yy) continue;if (abs(p[i].xx - p[j].xx) > p[i].yy - p[j].yy + 1) continue;// printf("+ %d,%d -> %d,%d :: %d\n", p[j].xx, p[j].yy, p[i].xx, p[i].yy, f[j]+1);if (f[j]+1 > f[i]) {f[i] = f[j]+1;}ans = std::max(ans, f[i]);}}printf("%d\n", ans);}return 0;
}
G. Goodbye
https://codeforces.com/gym/102803/problem/G
两个人玩游戏。给定一个 n(n≤105)n(n\le10^5)n(n≤105),每次操作可以取一个当前数的非平凡因子(非 111 和本身的因子,题目中说的真因子,但给的定义是对的)替代当前数,不能操作的人获胜,问先手是否获胜,如果获胜输出应该取的最大的数(直接获胜输出 000)。多测 T≤103T\le 10^3T≤103
脑筋急转弯,暴力预处理即可,复杂度 O(nn)O(n\sqrt n)O(nn)
队友代码:
#include<bits/stdc++.h>
#define N 233333
using namespace std;
bool cur1;
int n;
inline void Rd(int &res){char c;res=0;while(c=getchar(),c<48);do res=(res<<3)+(res<<1)+(c^48);while(c=getchar(),c>47);return;
}
int val[N];
void init(){int h=100000;for(int i=2;i<=h;i++){int cnt=0;val[i]=-1;for(int j=2;j*j<=i;j++)if(i%j==0){cnt++;if(val[j]==-1)val[i]=max(val[i],j);if(val[i/j]==-1)val[i]=max(val[i],i/j);}if(!cnt)val[i]=0;}
}
bool cur2;
int main(){// printf("%lf MB\n",(&cur2-&cur1)/1024.0/1024);
// freopen("data.txt","r",stdin);init();int T;Rd(T);while(T--){Rd(n);printf("%d\n",val[n]);}return 0;
}
H. Hate That You Know Me
https://codeforces.com/gym/102803/problem/H
σk(n)=∑d∣ndk\sigma_k(n)=\sum_{d|n}d^kσk(n)=d∣n∑dk
给定 0≤a,b<4,1≤n≤10120\le a,b<4,\;1\le n\le 10^{12}0≤a,b<4,1≤n≤1012,求
((∑i=1nσa(i))⊕(∑i=1nσb(i)))mod264((\sum_{i=1}^n\sigma_a(i))\oplus(\sum_{i=1}^n\sigma_b(i)))\mod 2^{64}((i=1∑nσa(i))⊕(i=1∑nσb(i)))mod264
眼瞎把 <<< 看成 ≤\le≤,导致队友推了一个四次方前缀和的通项(**出题人),浪费了好长时间(就说怎么那么多人会四次方前缀和的通项的)
⊕\oplus⊕ 两边的式子一样,只推一个即可
∑i=1nσk(i)=∑i=1n∑d∣idk=∑d=1ndk∑d∣i1=∑d=1ndk⋅⌊nd⌋\begin{aligned}\sum_{i=1}^n\sigma_k(i)&=\sum_{i=1}^n\sum_{d|i}d^k\\&=\sum_{d=1}^nd^k\sum_{d|i}1\\&=\sum_{d=1}^nd^k\cdot\lfloor\frac{n}{d} \rfloor \end{aligned}i=1∑nσk(i)=i=1∑nd∣i∑dk=d=1∑ndkd∣i∑1=d=1∑ndk⋅⌊dn⌋
一个整除分块再加一个 0/1/2/30/1/2/30/1/2/3 次方前缀和就做完了
队友代码:(可能写法有点不太一样)
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
bool cur1;
long long n;
inline void Rd(int &res){char c;res=0;while(c=getchar(),c<48);do res=(res<<3)+(res<<1)+(c^48);while(c=getchar(),c>47);return;
}
ull solve0(ull l,ull r){return r-l+1;}
ull calc1(ull a){if(a&1)return (a+1)/2*a;return a/2*(a+1);
}
ull solve1(ull l,ull r){return calc1(r)-calc1(l-1);
}
ull calc2(ull a){ull h1=a,h2=a+1,h3=2*a+1;if(h1&1)h2>>=1;else h1>>=1;if(h1%3==0)h1/=3;else if(h2%3==0)h2/=3;else h3/=3;return h1*h2*h3;
}
ull solve2(ull l,ull r){return calc2(r)-calc2(l-1);
}
ull calc3(ull a){return calc1(a)*calc1(a);
}
ull solve3(ull l,ull r){return calc3(r)-calc3(l-1);
}
ull solve(ull l,ull r,int f){if(f==0)return solve0(l,r);if(f==1)return solve1(l,r);if(f==2)return solve2(l,r);if(f==3)return solve3(l,r);
}
bool cur2;
int main(){// printf("%lf MB\n",(&cur2-&cur1)/1024.0/1024);
// freopen("data.txt","r",stdin);int a,b;scanf("%d%d%lld",&a,&b,&n);ull md=sqrt(n);ull res1=0,res2=0;for(int i=1;1ll*i*i<=n;i++){res1+=solve(i,i,a)*(n/i);res2+=solve(i,i,b)*(n/i);ull r=n/i,l=n/(i+1)+1;l=max(l,(ull)(i+1));res1+=solve(l,r,a)*i;res2+=solve(l,r,b)*i;
// printf("%d %llu %llu\n",i,l,r);
// printf("%d %llu %llu\n",i,res1,res2);}
// printf("%llu %llu\n",res1,res2);printf("%llu\n",res1^res2);return 0;
}
K. Keeping A Secret
https://codeforces.com/gym/102803/problem/K
有一棵树,给定所有点深度 ddd 和 bfsbfsbfs 序的排名区间 [1,x][1,x][1,x],求有多少颗满足限制的树
(算法是我后来yy出来的,可能和代码不太一样)
首先,bfsbfsbfs 序是按深度排的,可以先算出每个深度的标号范围,层内的标号互不影响。
其次,层间的父子关系和层内的标号可以分开计算(父子关系插个板就好了)。
最后,层内可以按 xxx 从小到大排序后一个个安排即可
队友代码:
#include<bits/stdc++.h>
#define N 100005
#define mod 1000000007
using namespace std;
bool cur1;
int n;
struct node{int d,x;
}Q[N];
inline bool cmp(node a,node b){return a.d==b.d?a.x<b.x:a.d<b.d;
}
inline void Rd(int &res){char c;res=0;while(c=getchar(),c<48);do res=(res<<3)+(res<<1)+(c^48);while(c=getchar(),c>47);return;
}
long long fac[N],infac[N];
inline long long C(int x,int y){return fac[y]*infac[x]%mod*infac[y-x]%mod;
}
void init(){fac[0]=infac[1]=infac[0]=1;for(int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;for(int i=2;i<=n;i++)infac[i]=mod-mod/i*infac[mod%i]%mod;for(int i=2;i<=n;i++)infac[i]=infac[i]*infac[i-1]%mod;
}
bool cur2;
int main(){// printf("%lf MB\n",(&cur2-&cur1)/1024.0/1024);
// freopen("data.txt","r",stdin);Rd(n);init();for(int i=1;i<=n;i++)Rd(Q[i].d),Rd(Q[i].x);sort(Q+1,Q+n+1,cmp);if((Q[1].d==1&&Q[2].d==1)||Q[1].d!=1){puts("0");return 0;}long long ans=1;for(int i=1,r,last=1;i<=n;i=r+1){r=i;while(r<n&&Q[r+1].d==Q[i].d)r++;if(i==1)continue;for(int j=i;j<=r;j++){int o=min(Q[j].x-j+1,r-j+1);if(o<1){puts("0");return 0;}ans=ans*o%mod;}ans=ans*C(last-1,r-i+last)%mod;last=r-i+1;}printf("%lld\n",ans);return 0;
}
L. Let’s Get Married
https://codeforces.com/gym/102803/problem/L
以 (0,0)(0,0)(0,0) 为起点 bfsbfsbfs,每个点的编号为 bfsbfsbfs 序,求给定 bfsbfsbfs 序对应的点坐标或给定点坐标对应的 bfsbfsbfs 序,强制在线,多测 T≤104T\le 10^4T≤104
(Due to some zz reason, WA/T了4发)
按哈密顿距离分层,每层 4n4n4n 个( nnn 为哈密顿距离)。层内顺序为上左(第一象限),上右(第二象限),右下(第四象限),下左(第三象限)。
给定 bfsbfsbfs 序找层的时候要二分(别问我怎么知道的)
代码:
#include<bits/stdc++.h>
/*
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
//*/
using namespace std;
typedef long long ll;
typedef double db;
const int N=100010,M=1000010,P=1e9+7;
const int inf=0x3f3f3f3f;
const int INF=0xcfcfcfcf;
const db eps=1e-9,pi=2*asin(1);
template<typename tn> void read(tn &n);
template<typename tn1,typename tn2> bool cmax(tn1 &x,tn2 y) { return x<y?x=y,true:false; }
template<typename tn1,typename tn2> bool cmin(tn1 &x,tn2 y) { return x>y?x=y,true:false; }
#define mp(x,y) make_pair(x,y)
#define pii pair<int,int>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pll pair<ll,ll>
int ADD(int x,int y,int p=P) { return x+y>=p?x+y-p:x+y; }
int MINUS(int x,int y,int p=P) { return x-y<0?x-y+p:x-y; }
#define plus(a,b) a=ADD(a,b)
#define minus(a,b) a=MINUS(a,b)
#define mul(a,b) a=1ll*(a)*(b)%P
#define mem(a,b) memset(a,b,sizeof(a))template<typename tn> void read(tn &n)
{tn s=0,flag=1;char ch=getchar();for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') flag=-1;for(;'0'<=ch&&ch<='9';ch=getchar()) s=s*10+ch-'0';if(ch=='.'){ch=getchar();tn r=0,R=1;for(;'0'<=ch&&ch<='9';ch=getchar()) r=r*10+ch-'0',R*=10;s+=r/R;}n=s*flag;
}int main()
{int n; read(n);ll xc=0,yc=0;for(int i=1;i<=n;i++){int opt; read(opt);if(opt==1){ll id; read(id);if(id==0){printf("%lld %lld\n",-xc,-yc);xc=0,yc=0;continue;}ll x,y;ll l=0,r=5e8;while(l+1<r){ll mid=l+r>>1;if(2ll*mid*(mid+1)<id) l=mid;else r=mid;}ll p=l+1;id-=2ll*p*(p-1);// cerr<<" "<<p<<" "<<id<<"\n";if(1<=id&&id<=2*p-1) // up + ?{if(id==1){x=p,y=0;}else{if(id&1) x=-id/2,y=p-id/2;else x=id/2,y=p-id/2;}}else if(2*p<=id&&id<=3*p-1) // right + down{id-=2*p;x=p-id,y=-id;}else if(3*p<=id&&id<=4*p) // down + left{id-=3*p;x=-id,y=id-p;}printf("%lld %lld\n",x-xc,y-yc);xc=x,yc=y;}else{ll x,y; read(x),read(y);ll p=abs(x)+abs(y);if(x==0&&y==0){printf("0\n");xc=0,yc=0;continue;}ll ans=2ll*p*(p-1);if(y>0){if(x==0) ans++;else if(x>0) ans+=2*x;else if(x<0) ans+=2*(-x)+1;}else if(x>0&&y<=0){ans+=2*p-y;}else if(x<=0&&y<=0){ans+=3*p-x;}printf("%lld\n",ans);xc=x,yc=y;}}return 0;
}
/*
1
2 -1 -1
*/
/*
1
1 79999999800000000
*/
总结
5h的比赛实际打了3h,由于只是队友之间的磨合,后面剩下三道难题都没花时间去做。
总结就是:队友nb!!!(有队友做大代码手就是爽)
The 15th Heilongjiang Provincial Collegiate Programming Contest题解 gym102803相关推荐
- The 15th Heilongjiang Provincial Collegiate Programming Contest (A、G、H、L)
The 15th Heilongjiang Provincial Collegiate Programming Contest A. August G. Goodbye H. Hate That Yo ...
- The 15th Heilongjiang Provincial Collegiate Programming Contest(A,C,F,G,H,L)
比赛链接 2021/2/7训练赛 Problem.A August 题解 不难发现上半部分是个半径为 a a a的圆,下半部分利用割补小正方形的方法得出等价于一个长为 2 a 2a 2a,宽为 2 b ...
- The 16th Heilongjiang Provincial Collegiate Programming Contest部分题解
The 16th Heilongjiang Provincial Collegiate Programming Contest 目录 D - Doin' Time 题目思路 题目代码 F - Func ...
- The 15th Jilin Provincial Collegiate Programming Contest
The 15th Jilin Provincial Collegiate Programming Contest A. Random Number Checker 签到 #include <bi ...
- 【ZJCPC2018 第15届 浙江省赛】The 15th Zhejiang Provincial Collegiate Programming Contest(MABLJK 6题)
补题地址:https://zoj.pintia.cn/home/news 搜索15th 本文按照通过率补的题 M. Lucky 7 题意:如果存在从给出的长为n的序列中选择一个数+b 可以被7整除,就 ...
- 第十五届吉林省赛The 15th Jilin Provincial Collegiate Programming Contest C.Random Number Generator(数学 BSGS)
文章目录 题意 题解 代码 总结 题目链接 题意 : 题解 : BSGS 代码 : #include <bits/stdc++.h> #include <unordered_map& ...
- 【21.10.24】The 15th Chinese Northeast Collegiate Programming Contest题解
A. Matrix(组合数+数学) #include <bits/stdc++.h> using namespace std; #define mod 998244353 ll fac[1 ...
- The 15th Chinese Northeast Collegiate Programming Contest 题解(CCPC压力测试?
CCPC压力测试用了这套题,和一个队友一起搞了.初期签到还算比较顺利,还碰到了挺多有意思的题目,做的好爽,但还是犯了很多低级错误,对于杭电要时时刻刻关同步或者scanf,并且写代码还是要仔细些. A. ...
- The 15th Chinese Northeast Collegiate Programming Contest部分题解
The 15th Chinese Northeast Collegiate Programming Contest 目录 E. Easy Math Problem 题目思路 题目代码 I. Takea ...
最新文章
- call、apply和bind的原生实现
- idea加载lombok插件
- matlab中将ebn0转snr,EbNo(EbN0)和SNR
- ansys 常用结构单元类型
- HTML+CSS 制作下拉菜单
- R语言潜在变量模型、探索性因子分析EFA、验证性因素分析(CFA)、结构方程建模(SEM)之间的关系、潜在变量模型常用包:ltm包、sem包、OpenMx包、Lavaan包、lsa包、ca包等
- C语言的lsb算法bmp信息隐藏,基于LSB算法的图像信息隐藏与检测.docx
- 前端学习笔记 HTML5 保姆级教程
- We‘re sorry but XXX doesn‘t work properly without JavaScript enabled. Please enable it to contin
- C语言汉诺塔问题图文详解
- python floor是什么意思_简单介绍Python中的floor()方法
- Xcode 13.4.1如何显示文件拓展名
- linux 创建子进程,Linux中使用fork创建子进程详解及示例程序
- Python 练习实例100例—5
- c/c++ substr()函数
- 北漂95后的2020年
- codevs 2832 6个朋友 并查集 解题报告
- 徒手撸设计模式-抽象工厂模式
- linux操作系统:x86架构,一个良好的运营环境
- Codeforces Round #577 (Div. 2)--B. Zero Array
热门文章
- 浏览器中java在什么位置_win10浏览器安装位置在哪里_如何找到win10浏览器的安装路径...
- 中秋节支付宝口令红包解析
- 飞桨图像分类入门——多种网络模型在手写数字识别的应用
- NFT Insider #75:The Sandbox 为Avatar 打造特别活动,Ambire 团队发起第一次官方治理投票
- 论文阅读笔记:Jointly Discovering Visual Objects and Spoken Words from Raw Sensory Input
- 有限元仿真分析技术中网格划分的类型与步骤
- 国内首款智能网联无人迷你巴士在东南大学首发试运行,车内没有配置方向盘...
- Python安装docx依赖包
- android dlna uri,DLNA 在自己的APP 中添加投屏功能
- AI+金融驱动金融信创“芯”生态