codeforces - 932 (div2)
A.将给的字符串正反输出两边
#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\n", x) #define Prl(x) printf("%lld\n",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 eps = 1e-9; const int maxn = 10010; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; char str[maxn]; int main(){ scanf("%s",str); int l = strlen(str); cout << str; for(int i = 0 ; i < l / 2; i ++) swap(str[i],str[l - i - 1]); cout << str << endl; return 0; }
B.暴力递推出所有数字对应的最终值,求每个最终值得前缀和,查询的时候O(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\n", x) #define Prl(x) printf("%lld\n",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 eps = 1e-9; const int maxn = 1e6 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int N,M,K; int fa[maxn]; int pre[10][maxn]; int cul(int x){ int ans = 1; while(x){ if(x % 10) ans *= x % 10; x /= 10; } return ans; } void init(){ for(int i = 1 ; i < 10; i ++){ fa[i] = i; } for(int i = 10; i < maxn; i ++){ fa[i] = fa[cul(i)]; } for(int i = 1; i < maxn; i ++){ for(int j = 1; j <= 9; j ++){ pre[j][i] = pre[j][i - 1]; } pre[fa[i]][i]++; } } int main(){ init(); Sca(N); while(N--){ int l,r,k; Sca3(l,r,k); Pri(pre[k][r] - pre[k][l - 1]); } return 0; }
C.主要在搞明白题意
先找出形如Ax + By = N,的正数x,y,N较小可以直接暴力
然后说明序列形成了x个长度A的环和y个长度B的环,构造输出就可以了
#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\n", x) #define Prl(x) printf("%lld\n",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 eps = 1e-9; const int maxn = 1e6 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; LL N; LL exgcd(LL a,LL b,LL &x,LL& y){ if(!a && !b) return -1; if(!b){ x = 1; y = 0; return a; } LL d = exgcd(b,a % b,y,x); y -= a / b * x; return d; } void solve(int &cnt,LL x,LL A){ for(int i = 1; i <= x; i ++){ int p = cnt; for(int j = 1; j < A; j ++){ cnt++; printf("%d ",cnt + 1); } cnt++; printf("%d ",p + 1); } } LL A,B; int main(){ scanf("%lld%lld%lld",&N,&A,&B); LL x,y; bool flag = 0; for(int i = 0; i * A <= N ; i ++){ if(!((N - i * A) % B)){ x = i; y = (N - i * A) / B; flag = 1; break; } } if(!flag){puts("-1"); return 0;} int cnt = 0; solve(cnt,x,A); solve(cnt,y,B); return 0; }
D.暴力肯定是不行的,极端数据是直接给一条从祖先到叶子权值递减的链,时间复杂度(2e5 * 2e5)
所以查询祖先要用树上倍增,时间复杂度nlogn
树上倍增维护每个节点的父亲值。
1.插入的时候如果当前节点的权值比给定的父亲节点权值小,就直接连上去
2.如果比给定的权值大,就倍增查找出他父亲的最小的比他权值大的祖先,将这个结点连到他祖先上去。
3.维护每个结点到根节点的一个前缀和
4.查询的之后同2,如果倍增查找到祖先前缀和-结点前缀和小于y的值,然后跳到y并计入两者深度差的贡献。
#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\n", x) #define Prl(x) printf("%lld\n",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 eps = 1e-9; const int maxn = 4e5 + 10; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; const int SP = 20; int N,M,K; int fa[maxn][SP],dep[maxn]; LL val[maxn],pre[maxn]; int main(){ int Q; Sca(Q); LL la = 0; int cnt = 1; val[0] = 2e18; dep[1] = 1; while(Q--){ LL op,x,y; scanf("%lld%lld%lld",&op,&x,&y); x ^= la; y ^= la; // cout <<"bug" <<op << " " << x << " " << y << endl; if(op == 1){ cnt++; val[cnt] = y; if(val[cnt] > val[x]){ for(int i = SP - 1; i >= 0 ; i --){ int f = fa[x][i]; if(val[f] < val[cnt]) x = f; } x = fa[x][0]; } dep[cnt] = dep[x] + 1; fa[cnt][0] = x; pre[cnt] = pre[x] + val[cnt]; for(int i = 1;i < SP; i ++) fa[cnt][i] = fa[fa[cnt][i - 1]][i - 1]; }else{ if(y < val[x]){ la = 0; puts("0"); continue; } y -= val[x]; la = 1; x = fa[x][0]; for(int i = SP - 1; i >= 0 && x != 0; i --){ int f = fa[x][i]; LL p = pre[x] - pre[f]; if(y >= p){ y -= p; la += (dep[x] - dep[f]); x = f; } } Prl(la); //la } } return 0; }