http://codeforces.com/contest/1422/problem/D
D. Returning Home
一个n*n的图
有些点就是可以瞬移 和象棋里车的规则一样,给你一些点,只要你在横纵坐标 就可以瞬移过去
考虑对x,y的列和行建图就可以了
#include <bits/stdc++.h> #define inf 0x3f3f3f3f #define inf64 0x3f3f3f3f3f3f3f3f using namespace std; typedef long long ll; const int maxn = 1e6+10; const int mod = 1e9+7; int head[maxn],nxt[maxn<<1],to[maxn<<1],w[maxn<<1],cnt; void add(int u,int v,ll c){ // printf("u = %d v = %d c = %lld ", u,v,c); ++cnt,to[cnt]=v,w[cnt]=c,nxt[cnt]=head[u],head[u]=cnt; ++cnt,to[cnt]=u,w[cnt]=c,nxt[cnt]=head[v],head[v]=cnt; } struct heapnode{ ll d,u; heapnode(ll d=0,ll u=0) : d(d),u(u) {} bool operator<(const heapnode &a) const{ return a.d<d; } }; ll d[maxn]; bool vis[maxn]; priority_queue<heapnode>que; void dijkstra(int s,int n){ while(!que.empty()) que.pop(); for(int i=0;i<=n;i++) d[i]=inf64,vis[i] = false; d[s]=0,que.push(heapnode(0,s)); while(!que.empty()){ heapnode x=que.top();que.pop(); int u=x.u; if(vis[u]) continue; vis[u]=true; for(int i=head[u];i;i=nxt[i]){ int v = to[i]; if(d[v]>d[u]+w[i]){ d[v]=d[u]+w[i]; que.push(heapnode(d[v],v)); } } } } int a[maxn],b[maxn],x[maxn],y[maxn]; int main(){ int n,m,sx,sy,gx,gy; scanf("%d%d",&n,&m); scanf("%d%d%d%d",&sx,&sy,&gx,&gy); for(int i=1;i<=m;i++){ scanf("%d%d",&x[i],&y[i]); a[i] = x[i],b[i] = y[i]; } sort(a+1,a+1+m); sort(b+1,b+1+m); add(0,3*m+1,abs(sx-gx)+abs(sy-gy)); for(int i=2;i<=m;i++){ add(i+m,i+m-1,abs(a[i]-a[i-1])); add(i+2*m,i+2*m-1,abs(b[i]-b[i-1])); } for(int i=1;i<=m;i++){ add(0,i,min(abs(sx-x[i]),abs(sy-y[i]))); add(i,3*m+1,abs(gx-x[i])+abs(gy-y[i])); int pos1 = lower_bound(a+1,a+1+m,x[i])-a; add(i,pos1+m,0); int pos2 = lower_bound(b+1,b+1+m,y[i])-b; add(i,pos2+2*m,0); } dijkstra(0,3*m+1); printf("%lld ", d[3*m+1]); return 0; }
C. Bargain
考虑 前缀对应后面多个后缀就可以了 求个后缀的后缀和
#include<bits/stdc++.h> #define fi first #define se second #define io std::ios::sync_with_stdio(false) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int P = 1e9+7, INF = 0x3f3f3f3f; ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} ll qpow(ll a,ll n){ll r=1%P;for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;} const int mod=1e9+7; const int maxn=1e5+10; ll pre[maxn],pree[maxn],suf[maxn],suff[maxn]; char a[maxn]; int main() { cin>>a+1; int n=strlen(a+1); ll ans=0; for(int i=1;i<=n;i++) { pre[i]=pre[i-1]*10+a[i]-'0'; pre[i]%=mod; if(i!=n) ans+=pre[i]; ans%=mod; pree[i]=pree[i-1]+pre[i]; pree[i]%=mod; } ll cnt=1; // cout<<ans<<endl; for(int i=n;i>=1;i--) { suf[i]=suf[i+1]+cnt*(a[i]-'0'); suf[i]%=mod; if(i!=1) ans+=suf[i]; ans%=mod; suff[i]=suff[i+1]+suf[i]; suff[i]%=mod; cnt*=10; cnt%=mod; } //cout<<ans<<endl; cnt=10; int num=1; for(int i=n-2;i>=1;i--) { ans+=pre[i]*cnt+suff[i+2]; ans%=mod; num++; cnt+=qpow(10,num); cnt%=mod; } cout<<ans<<endl; }