1011: [HNOI2008]遥远的行星
利用题目特殊条件暴力+乱搞,详见文章
代码
/* DOCUMENT NAME "20181128-bnds1011.cpp" CREATION DATE 2018-11-28 SIGNATURE CODE_20181128_BNDS1011 COMMENT [HNOI2008]遥远的行星 */ #include <cstdlib> #include <iostream> #include <cstdio> #include <cctype> #include <cmath> using namespace std; template<typename IntType> void read(IntType& val) { val = 0; int c; bool inv = false; while (!isdigit(c = getchar())) if (c == '-') inv = true; do { val = (val << 1) + (val << 3) + c - '0'; } while (isdigit(c = getchar())); if (inv) val = -val; } typedef long long ll; const int MaxN = 1e5 + 10; int n; double a; int m[MaxN]; ll sum[MaxN]; int main(int argc, char* argv[]) { read(n); scanf("%lf", &a); for (int i = 1; i <= n; i++) { read(m[i]); sum[i] = sum[i - 1] + m[i]; } for (int i = 1; i <= n; i++) { int fl = i * a + 1e-7; if (i <= 1000) { double ans = 0; for (int j = 1; j <= fl; j++) ans += (double)m[j] * m[i] / (i - j); printf("%lf\n", ans); } else printf("%lf\n", (double)sum[fl] * m[i] / (i - .5*fl)); } return 0; }
1015: [JSOI2008]星球大战starwar
题目没有要求强制在线,所以可以反着加点,用并查集维护一个点连出的所有边上两个连通块的合并,同时维护连通块大小作为当前点的答案
注意当前点在第一次合并入集合时并查集个数不减一
代码
/* DOCUMENT NAME "20181208-bzoj1015.cpp" CREATION DATE 2018-12-08 SIGNATURE CODE_20181208_BZOJ1015 COMMENT 1015: [JSOI2008]星球大战starwar */ #include <cstdlib> #include <iostream> #include <cstdio> #include <cctype> #include <cstring> using namespace std; template<typename IntType> void read(IntType& val) { val = 0; int c; bool inv = false; while (!isdigit(c = getchar())) if (c == '-') inv = true; do { val = (val << 1) + (val << 3) + c - '0'; } while (isdigit(c = getchar())); if (inv) val = -val; } #if (defined LOCAL) || (defined D) #define DEBUG(...) printf(__VA_ARGS__) #define PRINTARR(formatstr, arr, beginoff, size) \ do{printf(#arr ":"); \ for (int __i = beginoff; __i <= beginoff + size - 1; __i++) \ printf("\t%d", __i); \ printf("\n"); \ for (int __i = beginoff; __i <= beginoff + size - 1; __i++) \ printf("\t" formatstr, arr[__i]); \ printf("\n"); }while(false) #define PASS printf("Passing function \"%s\" on line %d\n", __func__, __LINE__) #define ASSERT(expr) do{\ if(!(expr)){\ printf("Debug Assertation Failed on line %d, in function %s:\n Expression: %s\n",__LINE__,__func__,#expr);\ abort();\ }\ }while(false) #else #define DEBUG(...) #define PRINTARR(a, b, c, d) #define PASS #define ASSERT(expr) #endif const int MaxM = 200000 + 10, MaxN = 2 * MaxM; int n, m; int x[MaxM], y[MaxM]; int k; int t[MaxN]; bool down[MaxN]; int ans[MaxN]; struct node { int v; node* next; }; node* h[MaxN]; node mem[2 * MaxM], *memtop = mem; #define ALLOCATE (++memtop) void addedge(int u, int v) { node* p = ALLOCATE; p->v = v; p->next = h[u]; h[u] = p; p = ALLOCATE; p->v = u; p->next = h[v]; h[v] = p; } int p[MaxN]; int setfind(int x) { if (p[x] < 0) return x; else return p[x] = setfind(p[x]); } void setunion(int x, int y) { x = setfind(x); y = setfind(y); if (x != y) { p[x] += p[y]; p[y] = x; } } int cnt; int main(int argc, char* argv[]) { read(n); read(m); for (int i = 1; i <= m; i++) { read(x[i]); read(y[i]); x[i]++; y[i]++; addedge(x[i], y[i]); } read(k); for (int i = 1; i <= k; i++) { read(t[i]); t[i]++; down[t[i]] = true; } memset(p, -1, sizeof(p)); for (int i = 1; i <= m; i++) { if (!down[x[i]] && !down[y[i]]) setunion(x[i], y[i]); } PRINTARR("%d", down, 1, n); PRINTARR("%d", p, 1, n); cnt = 0; for (int i = 1; i <= n; i++) if (!down[i] && p[i] < 0) cnt++; for (int i = k; i >= 1; i--) { ans[i] = cnt; int u = t[i]; cnt++; down[u] = false; for (node* p = h[t[i]]; p; p = p->next) { int v = p->v; if (!down[v] && setfind(u) != setfind(v)) { setunion(u, v); cnt--; } } } ans[0] = cnt; for (int i = 0; i <= k; i++) printf("%d\n", ans[i]); return 0; }
1012: [JSOI2008]最大数maxnumber
直接开一个长为n的线段树,模拟即可
代码
#include <cstdlib> #include <iostream> #include <cstring> #include <algorithm> #include <cctype> #include <cstdio> using namespace std; #if (defined LOCAL) || (defined D) #define DEBUG(...) printf(__VA_ARGS__) #define PRINTARR(formatstr, arr, beginoff, size) \ do{printf(#arr ":"); \ for (int __i = beginoff; __i <= beginoff + size - 1; __i++) \ printf("\t%d", __i); \ printf("\n"); \ for (int __i = beginoff; __i <= beginoff + size - 1; __i++) \ printf("\t" formatstr, arr[__i]); \ printf("\n"); }while(false) #define PASS printf("Passing function \"%s\" on line %d\n", __func__, __LINE__) #define ASSERT(expr) do{\ if(!(expr)){\ printf("Debug Assertation Failed on line %d, in function %s:\n Expression: %s\n",__LINE__,__func__,#expr);\ abort();\ }\ }while(false) #else #define DEBUG(...) #define PRINTARR(a, b, c, d) #define PASS #define ASSERT(expr) #endif template<typename IntType> void read(IntType& val) { val = 0; int c; bool inv = false; while (!isdigit(c = getchar())) if (c == '-') inv = true; do { val = (val << 1) + (val << 3) + c - '0'; } while (isdigit(c = getchar())); if (inv) val = -val; } char getnextchar(){ int c; while(iscntrl(c=getchar())||c==' '||c=='\t'); return c; } typedef long long ll; const int MaxN=200000+10; int m; ll p; struct node{ int left,right; ll max; node* lson,*rson; }; node* root; node mem[2*MaxN],*memtop=mem; #define ALLOCATE (++memtop) void build(int left=1,int right=m,node*& p=root){ p=ALLOCATE; p->left=left; p->right=right; if(left==right){ //p->max=0; }else{ int mid=(left+right)/2; build(left,mid,p->lson); build(mid+1,right,p->rson); //p->max=max(p->lson->max,p->rson->max); } } void setpnt(int pos,int val,node* p=root){ if(p->left==p->right){ ASSERT(p->left==pos); p->max=val; return; } if(p->lson->right>=pos) setpnt(pos,val,p->lson); else setpnt(pos,val,p->rson); p->max=max(p->lson->max,p->rson->max); } int querymax(int left,int right,node* p=root){ if(p->left==left&&p->right==right) return p->max; if(p->lson->right>=right) return querymax(left,right,p->lson); else if(p->rson->left<=left) return querymax(left,right,p->rson); else return max(querymax(left,p->lson->right,p->lson), querymax(p->rson->left,right,p->rson)); } int main(int argc, char* argv[]) { read(m);read(p); build(); int len=0,t=0; for(int i=1;i<=m;i++){ int c,x; c=getnextchar(); read(x); if(c=='A') setpnt(++len,(x+t)%p); else if(c=='Q') printf("%d\n",t=querymax(len-x+1,len)); } return 0; }