雅礼中学第四场20180109
T1
就是左端点排序后,然后如果可以到达下面一个点,那么对于
看这个,f[i]表示到了i这个点的方案数,当前边覆盖到了a[i].r
a[i].l-1 ------ a[i].r-1都可以转移过来,
然后对于其后面的来说,当前的边选不选无所谓,a[i].r---m都乘2
1 #include<cstring> 2 #include<algorithm> 3 #include<cmath> 4 #include<iostream> 5 #include<cstdio> 6 7 #define ls p<<1 8 #define rs p<<1|1 9 #define mod 1000000009 10 #define ll long long 11 #define N 500007 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} 17 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 21 int n,m; 22 int b[N]; 23 struct Node 24 { 25 int l,r; 26 }a[N]; 27 struct Date 28 { 29 ll add,cf,sum; 30 }tr[N*4]; 31 32 bool operator<(Node x,Node y){return x.l<y.l;} 33 void build(int p,int l,int r) 34 { 35 tr[p].cf=1; 36 if (l==r)return; 37 int mid=(l+r)>>1; 38 build(p<<1,l,mid),build(p<<1|1,mid+1,r); 39 } 40 void downdate(int p) 41 { 42 ll cf=tr[p].cf,add=tr[p].add;tr[p].cf=1,tr[p].add=0; 43 (tr[ls].cf*=cf)%=mod,(tr[ls].add*=cf)%=mod,(tr[ls].add+=add)%=mod; 44 (tr[rs].cf*=cf)%=mod,(tr[rs].add*=cf)%=mod,(tr[rs].add+=add)%=mod; 45 (tr[ls].sum*=cf)%=mod,(tr[ls].sum+=add)%=mod; 46 (tr[rs].sum*=cf)%=mod,(tr[rs].sum+=add)%=mod; 47 } 48 void update(int p) 49 { 50 tr[p].sum=tr[ls].sum+tr[rs].sum; 51 } 52 void modify(int p,int l,int r,int x,int y,ll jia,ll cf) 53 { 54 if (l==x&&y==r) 55 { 56 if (jia){(tr[p].add+=jia)%=mod;(tr[p].sum+=(r-l+1)*jia)%=mod;} 57 else 58 { 59 (tr[p].sum*=cf)%=mod; 60 (tr[p].add*=cf)%=mod; 61 (tr[p].cf*=cf)%=mod; 62 } 63 return; 64 } 65 downdate(p); 66 int mid=(l+r)>>1; 67 if (y<=mid) modify(p<<1,l,mid,x,y,jia,cf); 68 else if(x>mid) modify(p<<1|1,mid+1,r,x,y,jia,cf); 69 else modify(p<<1,l,mid,x,mid,jia,cf),modify(p<<1|1,mid+1,r,mid+1,y,jia,cf); 70 update(p); 71 } 72 int query(int p,int l,int r,int x,int y) 73 { 74 if (l==x&&y==r) return tr[p].sum; 75 downdate(p); 76 int mid=(l+r)>>1; 77 if (y<=mid) return query(p<<1,l,mid,x,y); 78 else if (x>mid) return query(p<<1|1,mid+1,r,x,y); 79 else return (query(p<<1,l,mid,x,mid)+query(p<<1|1,mid+1,r,mid+1,y))%mod; 80 update(p); 81 } 82 int main() 83 { 84 n=read(),m=read(); 85 for (int i=1;i<=n;i++)a[i].l=read(),a[i].r=read(); 86 sort(a+1,a+n+1); 87 for (int i=1;i<=m;i++)b[i]=read(); 88 sort(b+1,b+m+1); 89 for (int i=1;i<=n;i++) 90 { 91 (a[i].l=lower_bound(b+1,b+m+1,a[i].l)-b); 92 (a[i].r=upper_bound(b+1,b+m+1,a[i].r)-b)--; 93 // cout<<"i="<<i<<" "<<a[i].l<<" "<<a[i].r<<endl; 94 } 95 build(1,0,m); 96 modify(1,0,m,0,0,1,1); 97 int num=0; 98 for (int i=1;i<=n;i++) 99 { 100 if (a[i].l>a[i].r) 101 { 102 num++; 103 continue; 104 } 105 ll x=query(1,0,m,a[i].l-1,a[i].r-1); 106 modify(1,0,m,a[i].r,m,0,2); 107 modify(1,0,m,a[i].r,a[i].r,x,1); 108 } 109 ll ans=query(1,0,m,m,m); 110 for (int i=1;i<=num;i++)(ans*=(ll)2)%=mod; 111 printf("%lld\n",ans); 112 }
T2
因为x,y不同,所以一定有一位二进制不同,
但是无法区分谁大谁小
所以我们把其映射到12位上去,6个0,6个1,这样有924>920种
然后因为不同,所以找出哪一位,就是x为1,y为0的那一位,一定存在
然后就可以k=12来判断了。
代码很好实现
1 // Copyright (C) 2017 __debug. 2 3 // This program is free software; you can redistribute it and/or 4 // modify it under the terms of the GNU General Public License as 5 // published by the Free Software Foundation; version 3 6 7 // This program is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 // GNU General Public License for more details. 11 12 // You should have received a copy of the GNU General Public License 13 // along with this program; If not, see <http://www.gnu.org/licenses/>. 14 15 16 #include <bits/stdc++.h> 17 #include <ext/pb_ds/assoc_container.hpp> 18 #include <ext/pb_ds/priority_queue.hpp> 19 20 #define x first 21 #define y second 22 #define MP std::make_pair 23 #define SZ(x) ((int)(x).size()) 24 #define ALL(x) (x).begin(), (x).end() 25 #define DEBUG(...) fprintf(stderr, __VA_ARGS__) 26 #ifdef __linux__ 27 #define getchar getchar_unlocked 28 #define putchar putchar_unlocked 29 #endif 30 31 using std::pair; 32 using std::vector; 33 using std::string; 34 35 typedef long long LL; 36 typedef pair<int, int> Pii; 37 38 const int oo = 0x3f3f3f3f; 39 40 template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, true : false; } 41 template<typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, true : false; } 42 string procStatus() 43 { 44 std::ifstream t("/proc/self/status"); 45 return string(std::istreambuf_iterator<char>(t), std::istreambuf_iterator<char>()); 46 } 47 template<typename T> T read(T &x) 48 { 49 int f = 1; 50 char ch = getchar(); 51 for (; !isdigit(ch); ch = getchar()) 52 f = (ch == '-' ? -1 : 1); 53 for (x = 0; isdigit(ch); ch = getchar()) 54 x = 10 * x + ch - '0'; 55 return x *= f; 56 } 57 template<typename T> void write(T x) 58 { 59 if (x == 0) { 60 putchar('0'); 61 return; 62 } 63 if (x < 0) { 64 putchar('-'); 65 x = -x; 66 } 67 static char s[20]; 68 int top = 0; 69 for (; x; x /= 10) 70 s[++top] = x % 10 + '0'; 71 while (top) 72 putchar(s[top--]); 73 } 74 // EOT 75 76 const int LIM = 12; 77 78 int type, N; 79 vector<int> code; 80 81 void init() 82 { 83 for (int s = 0; s < (1 << LIM) && SZ(code) < N; ++s) { 84 if (__builtin_popcount(s) == LIM / 2) 85 code.push_back(s); 86 } 87 assert(SZ(code) == N); 88 } 89 90 int encode(int x, int y) 91 { 92 return 32 - __builtin_clz((code[x - 1] ^ code[y - 1]) & code[x - 1]); 93 } 94 95 bool decode(int q, int h) 96 { 97 return code[q - 1] >> (h - 1) & 1; 98 } 99 100 int main() 101 { 102 int T; 103 read(type); read(N); read(T); 104 init(); 105 while (T--) { 106 int x, y; 107 read(x); read(y); 108 if (type == 1) 109 printf("%d\n", encode(x, y)); 110 else 111 puts(decode(x, y) ? "yes" : "no"); 112 } 113 } 114 115 // 鍜畾闈掑北涓嶆斁鏉撅紝绔嬫牴鍘熷湪鐮村博涓€? 116 // -- 閮戠嚠銆婄鐭炽€?
T3
因为要最大化,编号不断增大,所以选了其父亲后一定会选最小的点,
但是不能直接贪心,要对于全局所有的点贪心,转化很巧妙。
代码附上,慢慢理解,
两个判断意思是,以前的原来点是没用的,并且不能是根,没有父亲。
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdio> 6 #include<queue> 7 8 #define ll long long 9 #define N 100007 10 using namespace std; 11 inline int read() 12 { 13 int x=0,f=1;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} 15 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 16 return x*f; 17 } 18 19 struct Node 20 { 21 int u,s,t;//u鍝釜鐐癸紝s鏄潈鍊煎拰锛宼鏄痵iz銆? 22 }; 23 bool operator >(Node x,Node y) 24 { 25 return (ll)x.s*y.t>(ll)y.s*x.t; 26 } 27 priority_queue<Node,vector<Node>,greater<Node> >q; 28 int n; 29 int par[N],fa[N],siz[N],sum[N],val[N*2],w[N],r[N]; 30 int cnt,hed[N],nxt[N*2],rea[N*2]; 31 ll res,ans[N]; 32 33 void add(int u,int v) 34 { 35 nxt[++cnt]=hed[u]; 36 hed[u]=cnt; 37 rea[cnt]=v; 38 } 39 void dfs(int u,int f) 40 { 41 for (int i=hed[u];i!=-1;i=nxt[i]) 42 { 43 int v=rea[i]; 44 if (v==f)continue; 45 par[v]=u,dfs(v,u); 46 } 47 } 48 int find(int num) 49 { 50 if (fa[num]!=num)fa[num]=find(fa[num]); 51 return fa[num]; 52 } 53 void solve(int rt) 54 { 55 for (int i=1;i<=n;i++) 56 { 57 fa[i]=i,siz[i]=1; 58 sum[i]=ans[i]=w[i]; 59 q.push((Node){i,w[i],1}); 60 } 61 dfs(rt,0); 62 for (int i=1;i<n;) 63 { 64 Node now=q.top();q.pop(); 65 if (now.t!=siz[now.u]||now.u==rt)continue; 66 i++; 67 int u=find(par[now.u]),v=now.u; 68 ans[u]+=ans[v]+(ll)sum[v]*siz[u]; 69 res=max(res,ans[u]); 70 fa[v]=u,siz[u]+=siz[v],sum[u]+=sum[v]; 71 q.push((Node){u,sum[u],siz[u]}); 72 } 73 while(!q.empty())q.pop(); 74 } 75 int main() 76 { 77 memset(hed,-1,sizeof(hed)); 78 n=read(); 79 for (int i=1;i<n;i++) 80 { 81 int x=read(),y=read(); 82 add(x,y),add(y,x); 83 } 84 for (int i=1;i<=n;i++) 85 w[i]=read(),r[i]=read(); 86 for (int i=1;i<=n;i++) 87 if (r[i])solve(i); 88 printf("%lld\n",res); 89 }