Ultraviolet A 12657 boxes in a line
Simulation
Fzu 1876 jinyuetuan does not speak
view code#include <iostream>using namespace std;int main(){ long long n,m,p,ans=1; while(cin>>n>>m>>p){ ans=1; for(int i=n;i<n+m;i++){ ans=ans*i%p; if(ans==0)break; } cout<<ans<<endl; } return 0;}
Zoj 3684 destroy
view code#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int N = 10010;int _, cas=1, n, m,pre[N], ans=0;int in[N],dp[N<<1];bool vis[N<<1];struct edge{ int u, v, w, p, next; edge() {} edge(int u, int v, int w, int p, int next):u(u),v(v),w(w),p(p),next(next) {}}e[N<<1];int ecnt;int dfs(int u, int h, int p){ int ans = 0; for(int i=pre[u]; ~i; i=e[i].next) { int v = e[i].v; if(v==p) continue; if(!vis[i]) dp[i] = dfs(v, e[i].w, u),vis[i] = 1; ans = max(dp[i], ans); } return h+ans;}void addedge(int u, int v, int w, int p){ e[ecnt] = edge(u, v, w, p, pre[u]); pre[u] = ecnt++; e[ecnt] = edge(v, u, w, p, pre[v]); pre[v] = ecnt++;}//bool dfs2(int u, int lim, int p)//{// if(in[u]==1) return 0;// for(int i=pre[u]; ~i; i=e[i].next)// {// int v = e[i].v;// if(v==p || e[i].p<=lim) continue;// if(!dfs2(v, lim, u)) return 0;// }// return 1;//}void dfs3(int u, int h, int p){ if(in[u]==1) { ans = max(ans, h); return ; } for(int i=pre[u]; ~i; i=e[i].next) { int v = e[i].v; if(v==p) continue; dfs3(v, min(h,e[i].p), u); }}void solve(){ memset(pre, -1, sizeof(pre)); memset(in, 0, sizeof(in)); ecnt = 0; int u, v, w, p, l = 0, r = 0; for(int i=1; i<n; i++) { scanf("%d%d%d%d", &u, &v, &w, &p); addedge(u, v, w, p); in[u]++; in[v]++;// r = max(p, r); } int s=0, Min=INF, tmp; memset(vis, 0, sizeof(vis)); for(int i=1; i<=n; i++) { tmp = dfs(i, 0, 0); if(tmp<Min) s = i, Min=tmp; } ans = 0; dfs3(s, INF, 0);// while(l<=r)// {// int mid = (l+r)>>1;// if(dfs2(s, mid, 0)) ans =mid, r=mid-1;// else l = mid+1;// } printf("%d\n", ans);}int main(){// freopen("in.txt", "r", stdin); while(scanf("%d", &n)>0) solve(); return 0;}
Zoj 3676 Edward's Cola plan)
view code#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long ll;const int INF = 0x3f3f3f3f;const int N = 100010;int _, cas=1, n, m;int suma[N], sumb[N], ans[10010];struct edge{ int a, b, c; edge() {} edge(int a, int b, int c):a(a),b(b),c(c) {} bool operator < (const edge &o) const{ return c>o.c; }}e[N];struct node{ int v, id; bool operator < (const node &o) const{ return v>o.v; }}p[10010];void solve(){ int a, b; for(int i=1; i<=n; i++){ scanf("%d%d",&a, &b); e[i] = edge(a,b, b-a); } sort(e+1, e+1+n); for(int i=1; i<=n; i++) { suma[i] = suma[i-1] + e[i].a; sumb[i] = sumb[i-1] + e[i].b; } for(int i=0; i<m; i++) { scanf("%d", &p[i].v); p[i].id = i; } sort(p, p+m); int j = 1, M; for(int i=0; i<m; i++) { M = p[i].v; while(j<=n && e[j].c>M) j++; ans[p[i].id] = sumb[j-1]-M*(j-1)+suma[n]-suma[j-1]; } for(int i=0; i<m; i++) { printf("%d\n", ans[i]); }}int main(){// freopen("in", "r", stdin); while(scanf("%d%d", &n,&m)>0) solve(); return 0;}
Zoj 2899 Hangzhou tour
Zoj 3724 icecream line segment tree, offline, quite classic
Sum [N] indicates the prefix and
Case 1:
If it is the shortest distance from u to V, (A to B is a shortcut with the length of Len)
If you do not take the shortcut dis1 = sumv-Sumu;
If the shortcut dis2 = sumv-Sumu + len-(sumb-SUMA) is used ).
If you do not take a shortcut, You can see whether len-(sumb-SUMA) is less than 0, (equal to 0, it doesn't matter if you leave)
If there are multiple shortcuts and there are shortcuts, follow the one with the smallest len-(sumb-SUMA) shortcut.
Case 2:
If it is the shortest distance from u to V, (A to B is a shortcut with the length of Len)
Assume that there is no shortcut to a circle, that is, dis1 = sumn-Sumu + sumv;
Shortcut dis2 = Suma-Sumu + sumv-sumb + Len;
Do you want to take shortcuts? (SUMA-sumb + Len)-whether the sumn is greater than 0,
Of course, this is definitely a shortcut. This is only one way to judge the shortest path when there are multiple shortcuts.
Take the minimum shortcut (SUMA-sumb + Len)-sumn.
The minimum values are maintained using the line segment tree.
view code#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;typedef long long ll;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const ll INF = 1LL<<60;const int N = 100010;int n, m, T;ll Min[N<<2], sum[N], ans[N<<1];struct seg{ int l, r; ll w; seg() {} seg(int l, int r, ll w):l(l),r(r),w(w) {} bool operator < (const seg &o) const{ return r<o.r; }}e1[N<<1], e2[N<<2], ask1[N<<2], ask2[N<<2];int ecnt1, ecnt2, acnt1, acnt2;bool cmp(const seg a, const seg b){ return a.l<b.l;}void Up(int rt){ Min[rt] = min(Min[rt<<1], Min[rt<<1|1]);}void build(int l, int r, int rt){ Min[rt] = INF; if(l==r) return ; int m = (l+r)>>1; build(lson); build(rson);}void update(int p, ll c, int l, int r, int rt){ if(l==r) { Min[rt] = min(Min[rt], c); return ; } int m = (l+r)>>1; if(p<=m) update(p, c, lson); else update(p, c, rson); Up(rt);}ll query(int L, int R, int l, int r, int rt){ if(L<=l && R>=r) return Min[rt]; int m = (l+r)>>1; ll ans = INF; if(L<=m) ans = min(ans, query(L, R, lson)); if(R>m) ans = min(ans, query(L, R, rson)); return ans;}void solve(){ int a, b, c; for(int i=2; i<=n; i++) { scanf("%d", &a); sum[i] = sum[i-1] + a; } ecnt1 = ecnt2 = acnt1 = acnt2 = 0; while(m--) { scanf("%d%d%d", &a, &b, &c); if(a<b) { if(sum[a] - sum[b] + c>0) continue; e1[ecnt1++] = seg(a, b, c-(sum[b]-sum[a])); } else e2[ecnt2++] = seg(b, a, (sum[a]-sum[b]+c)-sum[n]); } scanf("%d", &T); for(int i=0; i<T; i++) { scanf("%d%d", &a, &b); if(a<b) ask1[acnt1++] = seg(a, b, i); else if(a>b)ask2[acnt2++] = seg(b, a, i); else ans[i] = 0; } sort(ask1, ask1+acnt1); sort(e1, e1+ecnt1); int i=0, j=0; build(1, n, 1); for(; i<acnt1; i++) { while(j<ecnt1 && e1[j].r<=ask1[i].r) { update(e1[j].l, e1[j].w, 1, n, 1); j++; } ll t = min((ll)0,query(ask1[i].l, ask1[i].r, 1, n, 1)); ans[ask1[i].w] = sum[ask1[i].r] - sum[ask1[i].l] + t; } sort(ask2, ask2+acnt2, cmp); sort(e2, e2+ecnt2, cmp); build(1, n, 1); for(i = 0, j = 0; i<acnt2; i++) { while(j<ecnt2 && e2[j].l<=ask2[i].l) { update(e2[j].r, e2[j].w, 1, n, 1); j++; } ans[ask2[i].w] = sum[n]+sum[ask2[i].l]-sum[ask2[i].r]+query( ask2[i].r, n, 1, n, 1);// printf("(%d, %d)first : %I64d\n",ask2[i].l,ask2[i].r,ans[ask2[i].w]); } for(int i=0; i<T; i++) { printf("%lld\n", ans[i]); }}int main(){// freopen("in.txt", "r", stdin); while(scanf("%d%d", &n, &m)>0) solve(); return 0;}