The Preliminary Contest for ICPC Asia Nanjing 2019
Holy Grail
#include <bits/stdc++.h>
using namespace std;
const int maxn=10000;
int n,m;
struct Spfa {
struct Edge {
int next, to, w;
} e[maxn];
int head[maxn], v[maxn], d[maxn], tol;
void add(int u, int v, int w) {
tol++;
e[tol].to = v;
e[tol].next = head[u];
e[tol].w = w;
head[u] = tol;
}
queue<int> q;
int spfa(int s, int t) {
memset(d, 0x3f, sizeof(d));
memset(v, 0, sizeof(v));
d[s] = 0;
v[s] = 1;
q.push(s);
while (!q.empty()) {
int x = q.front();
q.pop();
v[x] = 0;
for (int i = head[x]; i; i = e[i].next) {
if (d[e[i].to] > d[x] + e[i].w) {
d[e[i].to] = d[x] + e[i].w;
if (v[e[i].to] == 0) {
v[e[i].to] = 1;
q.push(e[i].to);
}
}
}
}
return d[t] == 0x3f ? -1 : d[t];
}
void init() {
memset(head, 0, sizeof(head));
tol = 0;
}
} S;
int main(){
int _;
scanf("%d",&_);
while (_--){
S.init();
scanf("%d%d",&n,&m);
for (int i=1,u,v,w;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
S.add(u,v,w);
}
for (int i=1,u,v;i<=6;i++){
scanf("%d%d",&u,&v);
int ans=S.spfa(v,u);
printf("%d\n",-ans);
S.add(u,v,-ans);
}
}
}
Greedy Sequence
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+50;
struct CT{
#define mid (l+r)/2
int tot,sum[N*30],ls[N*30],rs[N*30];
void init(){
tot=0;
}
int build(int l,int r){
int rt=++tot;
sum[rt]=ls[rt]=rs[rt]=0;
if(l<r){
ls[rt]=build(l,mid);
rs[rt]=build(mid+1,r);
}
return rt;
}
int update(int pre,int l,int r,int x){
int rt=++tot;
ls[rt]=ls[pre];
rs[rt]=rs[pre];
sum[rt]=sum[pre]+1;
if(l<r){
if(x<=mid){
ls[rt]=update(ls[pre],l,mid,x);
}else{
rs[rt]=update(rs[pre],mid+1,r,x);
}
}
return rt;
}
int query(int u,int v,int l,int r,int k){
if(l>=r){
if(l<k && sum[v]-sum[u]){
return l;
}else{
return 0;
}
}
if(k<=mid+1 || sum[rs[v]]-sum[rs[u]]==0){
return query(ls[u],ls[v],l,mid,k);
}
int t=query(rs[u],rs[v],mid+1,r,k);
if(t){
return t;
}else{
return query(ls[u],ls[v],l,mid,k);
}
}
void debug(int rt,int l,int r){
printf("%d %d %d\n",l,r,sum[rt]);
if(l==r){
return;
}
debug(ls[rt],l,mid);
debug(rs[rt],mid+1,r);
}
}ac;
int tr[N];
int T,n,k,a[N],p[N],ans[N];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
p[a[i]]=i;
}
ac.init();
tr[0]=ac.build(1,n);
for(int i=1;i<=n;i++){
tr[i]=ac.update(tr[i-1],1,n,a[i]);
}
ans[1]=1;
for(int i=2;i<=n;i++){
int L=max(1,p[i]-k);
int R=min(n,p[i]+k);
int x=ac.query(tr[L-1],tr[R],1,n,i);
ans[i]=ans[x]+1;
}
for(int i=1;i<=n;i++){
printf("%d%c",ans[i],i==n?'\n':' ');
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int tot,t[maxn*30],ans[maxn],L[maxn*30],R[maxn*30],a[maxn],b[maxn],n,c[maxn],k;
vector<int>root;
int build(int l,int r) {
int id = ++tot;
t[id] = 0;
if (l == r) return id;
int mid = (l + r) >> 1;
L[id] = build(l, mid);
R[id] = build(mid + 1, r);
return id;
}
void insert1(int id1,int x) {
int id2 = ++tot;
root.push_back(id2);
t[id2] = t[id1] + 1;
int l = 1, r = n;
while (l < r) {
int mid = (l + r) >> 1;
if (x <= mid) {
r = mid;
L[id2] = ++tot;
R[id2] = R[id1];
id2 = tot;
id1 = L[id1];
} else {
l = mid + 1;
R[id2] = ++tot;
L[id2] = L[id1];
id2 = tot;
id1 = R[id1];
}
t[id2] = t[id1] + 1;
}
}
int query1(int id,int l,int r,int x) {
if (x >= a[r]) return t[id];
else if (x < a[l]) return 0;
int res = 0;
int mid = (l + r) >> 1;
if (x <= a[mid]) res = query1(L[id], l, mid, x);
else {
res += t[L[id]];
res += query1(R[id], mid + 1, r, x);
}
return res;
}
int query(int l,int r,int LL,int RR,int k)
{
if (l==r)
return l;
int mid=(l+r)>>1;
int tmp=t[L[RR]]-t[L[LL]];
if (k<=tmp)
{
return query(l,mid,L[LL],L[RR],k);
}
else
{
return query(mid+1,r,R[LL],R[RR],k-tmp);
}
}
int main() {
int _;
scanf("%d", &_);
while (_--) {
tot = 0;
scanf("%d%d", &n, &k);
root.clear();
for (int i = 1; i <= n; i++) {
ans[i]=0;
scanf("%d", &b[i]);
a[i] = b[i];
c[a[i]] = i;
}
sort(a + 1, a + 1 + n);
n = unique(a + 1, a + n + 1) - (a + 1);
root.push_back(build(1, n));
for (int i = 1; i <= n; i++) {
insert1(root[i - 1],b[i]);
}
for (int i = 1; i <= n; i++) {
int id = c[i];
while (1) {
ans[i]++;
int kk = query1(root[min(n, id + k)], 1, n, b[id]) - query1(root[max(1, id - k) - 1], 1, n, b[id]) - 1;
if (kk == 0) break;
id = c[a[query(1, n, root[max(1, id - k) - 1], root[min(n, id + k)], kk)]];
if (ans[b[id]]) {
ans[i] += ans[b[id]];
break;
}
}
}
for (int i = 1; i <= n; i++) {
if (i != n) printf("%d ", ans[i]); else printf("%d\n", ans[i]);
}
}
return 0;
}
The beautiful values of the palace
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
int n,m,p,tot;
ll ans[maxn],d[maxn];
struct node {
int x, y, id, flag;
node(int _x = 0, int _y = 0, int _id = 0, int _flag = 0) : x(_x), y(_y), id(_id), flag(_flag) {};
bool operator<(const node &b) const {
return y < b.y;
}
}q[maxn*4];
struct node1 {
int x, y, val;
node1(int _x = 0, int _y = 0, int _val = 0) : x(_x), y(_y), val(_val) {};
bool operator<(const node1 &b) const {
return y < b.y;
}
}a[maxn];
ll c[maxn*2];
int lowbit(int x){
return x&-x;
}
void add(int x,ll val){
if (x==0) return;
while (x<maxn){
c[x]+=val;
x+=lowbit(x);
}
}
ll query(int x) {
ll ret = 0;
while (x) {
ret += c[x];
x -= lowbit(x);
}
return ret;
}
void solve() {
int pos = 1;
for (int i = 1; i <= tot; i++) {
while (pos <= m && a[pos].y <= q[i].y) {
add(a[pos].x, a[pos].val);
pos++;
}
ans[q[i].id] += query(q[i].x) * q[i].flag;
}
}
ll sum(ll x) {
ll ret = 0;
while (x) {
ret += x % 10;
x /= 10;
}
return ret;
}
ll get(ll x,ll y,ll n) {
int cx = n / 2 + 1;
int cy = n / 2 + 1;
ll k = max(abs(x - cx), abs(y - cy));
if (k == 0) return n * n;
ll res = d[k - 1];
if (y - cy == k && x < cx + k)
res += cx + k - x;
else if (cx - x == k && y < cy + k)
res += k * 2 + cy + k - y;
else if (cy - y == k && x > cx - k)
res += k * 4 + x + k - cx;
else if (x - cx == k) res += k * 6 + y - cy + k;
res = n * n - res;
return res+1;
}
int main() {
int _;
d[0]=1;d[1]=8;
for (int i=2;i<=maxn;i++) d[i]=d[i-1]+8;
for (int i=1;i<=maxn;i++) d[i]+=d[i-1];
scanf("%d", &_);
while (_--) {
scanf("%d%d%d", &n, &m, &p);
for (int i = 0; i <= 2 * n; i++) c[i] = 0;
for (int i = 0; i <= p; i++) ans[i] = 0;
for (int i = 1, x, y; i <= m; i++) {
scanf("%d%d", &x, &y);
a[i] = node1(x, y, sum(get(x, y, n)));
}
tot = 0;
sort(a + 1, a + m + 1);
for (int i = 1, x1, yy, x2, y2; i <= p; i++) {
scanf("%d%d%d%d", &x1, &yy, &x2, &y2);
q[++tot] = node(x1 - 1, yy - 1, i, 1);
q[++tot] = node(x1 - 1, y2, i, -1);
q[++tot] = node(x2, yy - 1, i, -1);
q[++tot] = node(x2, y2, i, 1);
}
sort(q + 1, q + tot + 1);
solve();
for (int i = 1; i <= p; i++) {
printf("%lld\n", max(0ll, ans[i]));
}
}
return 0;
}
super_log
所给的函数是一个递归的形式,每递归一次就是+1,容易推出最后X = ((a^a)^a)^a......【b个a的幂】,算是一个原题【BZOJ-3884】(简单版),【CF-906D】(加强版),实现就是欧拉广义降幂的递归形式,注意b=0时输出(1 mod m)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a,b,mod;
ll eular(ll n) {
ll phi = n;
for (ll i = 2; i * i <= n; i++) {
if (n % i == 0) {
phi = phi * (i - 1) / i;
while (n % i == 0) n = n / i;
}
}
if (n > 1) phi = phi * (n - 1) / n;
return phi;
}
ll pow_mod(ll a,ll x,ll mod) {
ll res = 1;
while (x) {
if (x & 1) res = res * a % mod;
a = a * a % mod;
x = x >> 1;
}
return res;
}
ll solve(ll a,ll b,ll mod) {
if (mod==1)
return 0;
if (b==0)
return 1;
ll phi = eular(mod);
ll p = solve(a, b-1, phi);
if (p < phi && p) return pow_mod(a, p, mod); else return pow_mod(a, p + phi, mod);
}
int main() {
int _;
scanf("%d", &_);
while (_--) {
scanf("%d%d%d", &a, &b, &mod);
if (b == 0) {
printf("%d\n", 1 % mod);
} else {
printf("%d\n", solve(a, b, mod) % mod);
}
}
return 0;
}