11月9日——离noip还有10天
来源:互联网 发布:人工智能专业就业前景 编辑:程序博客网 时间:2024/04/29 23:21
今天“贪心了”,然后GG地更凶了,连wyy都没考过;
哎,人生在世不称意,不如自挂东南枝;
昨天那份帖子一个晚上就有60多人看,好开心,
但是现在还是定格在60几
不bb了,直接上题。
子序列
给定 3 个字符串,求它们的最长公共子序列。
输入
第一行一个整数 n,表示三个字符串的长度
接下来三行,每行是一个长度为 n 只包含小写字母的字符串。
输出
输出最长公共子序列的长度。
输入样例
4
abac
abbc
cbca输出样例
2提示
30% n<=10
100% n<=120
超级大水题
二维改三维
注意:
ab与bc的lcs=1;
bc与ca的lcs=1;
ca与ab的lcs=1;
但是 ab与bc与ca的lcs=0;
所以一开始我的方法就GG了
正解
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<queue>#include<algorithm>#include<vector>#include<cstdlib>#include<cmath>#include<ctime>#include<stack>#define rez(i,x,y) for(int i=x;i>=y;i--)#define res(i,x,y) for(int i=x;i<=y;i++)#define minme(x,y) x=min(x,y)#define INF 2100000000#define ll long long#define clr(x) memset(x,0,sizeof(x))#define N 100005#define NAME "subq"using namespace std;char x[200],y[200],z[200];int n; int dp[200][200][200];int LCS(){ for(int i = 1; i <= n; ++i) { for(int j = 1; j <= n; ++j) { for(int k = 1; k <= n; ++k) { dp[i][j][k] = max(dp[i][j-1][k], dp[i-1][j][k]); dp[i][j][k] = max(dp[i][j][k], dp[i][j][k-1]); if(x[i] == y[j] && x[i] == z[k]) dp[i][j][k] = max(dp[i][j][k], dp[i-1][j-1][k-1] + 1); } } } return dp[n][n][n];} int main(){ freopen(NAME".in","r",stdin); freopen(NAME".out","w",stdout); cin>>n; scanf("%s",x+1); scanf("%s",y+1); scanf("%s",z+1); int lcs_max_len=LCS(); cout<<lcs_max_len<<endl; return 0;}
dun
【问题描述】
定义两个素数是连续的当且仅当这两个素数之间不存在其他的素数(如
(7,11),(23,29)。给定N,k,在不超过N的正整数中求能够分解为k个连续的素数
的和的最大的那个是多少。
【输入格式】
第一行一个正整数T代表数据组数。
接下来T行每行两个正整数N, k代表一组询问。
【输出格式】
输出共T行,每行一个整数代表答案;如果找不到这样的数,输-1。
【样例输入】
3
20 2
20 3
20 4【样例输出】
18
15
17【样例解释】
╭︿︿︿╮
{/ o o /}
( (oo) )
︶︶︶
(说真的,好像认识一下这个把猪头当做样例解释的出题人)
【数据规模与约定】对于20%的数据,1 <=N<=100。
对于40%的数据,T= 1。
对于60%的数据,所有的询问的N相等。
对于100%的数据,1<=T<=2000,1<=N<=10^6。
筛素数
先介绍网上广为流传的O(n)法,其实质是O(nloglogn)
借用这位博主的代码
void sieveTwo(){ int p,q; int end = sqrt(N+0.5); for(p = 2; p!=end; ++p ){ if(!arr[p]){ for(q = p; p*q <= N; ++q){ for(int k= p*q; k<= N; k*=p) arr[k] = 1; } } } }
虽然比起一般的筛法的确优一点,但并不是真正的O(n);
然后是杨z大神的代码(真正的可以近似达到O(n)的复杂度):
具体原因这位博主写得更详细。
这里不再赘述。
#include<cstdio>#include<cstring>#include<ctime>#include<iostream>#include<algorithm>#define LL long long using namespace std;const int N=1e7;int prime[N+5],cnt,n,k,T,ans,pos;bool mark[N+5];LL sum[N+5];int readint(){ int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();} return x;}void init(){ for (int i=2;i<=n;i++) { if (!mark[i]) prime[++cnt]=i; for (int j=1;j<=cnt;j++) { if (i*prime[j]>n) break; mark[i*prime[j]]=true; if (i%prime[j]==0) break; } } for (int i=1;i<=cnt;i++) sum[i]=sum[i-1]+prime[i];}int main(){ freopen("dun.in","r",stdin); cin>>n; init(); //cout<<clock()<<endl<<endl; return 0;}
小编用clock()测试了包括一般筛法在内的三种方法,结果如下:
可以看见最后一种既是O(n)的复杂度,要快很多。
题解
言归正传,这道题就可以先用任意一种较快的筛法,筛完后再用二分前缀和求解即可
code
#include<cstdio>#include<cstring>#include<cctype>#include<algorithm>#define LL long long using namespace std;const int N=1e6;int prime[N+5],cnt,n,k,T,ans,pos;bool mark[N+5];LL sum[N+5];int readint(){ int x=0; char ch=getchar(); while (!isdigit(ch)) ch=getchar(); while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();} return x;}void init(){ for (int i=2;i<=N;i++) { if (!mark[i]) prime[++cnt]=i; for (int j=1;j<=cnt;j++) { if (i*prime[j]>N) break; mark[i*prime[j]]=true; if (i%prime[j]==0) break; } } for (int i=1;i<=cnt;i++) sum[i]=sum[i-1]+prime[i];}int main(){ freopen("dun.in","r",stdin); freopen("dun.out","w",stdout); init(); T=readint(); while (T--) { n=readint(); k=readint(); ans=-1; pos=upper_bound(prime+1,prime+cnt+1,n)-prime-1; for (int i=pos;i>=k;i--) if (sum[i]-sum[i-k]<=n) { ans=sum[i]-sum[i-k]; break; } printf("%d\n",ans); } return 0;}
标答二
#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;const int maxn=1000010;int prime[maxn],cnt;bool flag[maxn];long long sum[maxn];int main(){ for (int a=2;a<=1000000;a++) { if (!flag[a]) { cnt++; prime[cnt]=a; } for (int b=1,c;b<=cnt && (c=a*prime[b])<=1000000;b++) { flag[c]=true; if (a % prime[b]==0) break; } } for (int a=1;a<=cnt;a++) sum[a]=prime[a]+sum[a-1]; int t; scanf("%d",&t); for (;t--;) { int n,k; scanf("%d%d",&n,&k); int l=1,r=cnt-k+2; if (r<=1) { printf("-1\n"); continue; } while (l+1!=r) { int m=(l+r)>>1; if (sum[m+k-1]-sum[m-1]>n) r=m; else l=m; } if (sum[l+k-1]-sum[l-1]<=n) printf("%d\n",(int)(sum[l+k-1]-sum[l-1])); else printf("-1\n"); } return 0;}
然后就可以AC
发放粮食
描述
有一个村庄在闹饥荒,善良而土豪的 YGH 决定给他们发放救济粮,该村庄有 n 户人家,
每两户人家之间只有一条路可以互相到达,即这些人家之间形成一棵树。现在 YGH 会以这
样的形式给他们发放粮食,选择两户人家,然后对这两个户人家路径上的所有人家都发放一
袋种类为 w 的救济粮。在完成一系列发放任务后,YGH 想知道每一户人家收到的粮食中数
量最多的是哪一种。
输入
第一行两个数 n,q,其中 n 表示村庄共有几户人家,q 表示 YGH 一共发放了几次粮
食。接下来 n-1 行,每行两个数 x y,表示编号为 x 和 y 的两户人家之间连有边。接下
来 q 行,每行三个数 x y w,表示 YGH 选择了 x 到 y 的路径,对每户人家发放 1 袋种
类为 w 的粮食。
输出
输出 n 行,第 i 行输出编号为 i 的人家收到的粮食中数量最多的种类号,如果有多个
数量相同的粮食,输出其中最小的种类号,如果没有收到粮食,输出 0
样例输入
[1]
2 4
1 2
1 1 1
1 2 2
2 2 2
2 2 1
[2]
5 3
1 2
3 1
3 4
5 3
2 3 3
1 5 2
3 3 3
样例输出
[1]
1
2
[2]
2
3
3提示
0
2对于 40% 的数据 n<=1000,q<=1000,1<=w<=1000
对于 100% 的数据 n<=100000,q<=100000,1<=w<=100000 1<=x,y<=n
什么树链剖分?不懂!!!
线段数+A*(启发式搜索)+内存回收乱搞,GG……
所以还是树链剖分吧!
学习中……请勿打扰
。。。。
崩掉的标答
#include <cstdio>#include <cstring>#include <vector>#define lson rt<<1#define rson rt<<1|1#define maxn 100010using namespace std;struct Pair { int ind, val; Pair(){} Pair( int ii, int vv ) : ind(ii), val(vv) {}};int n, q;vector<int> g[maxn], flag[maxn];int siz[maxn], son[maxn], dep[maxn], pre[maxn], top[maxn], vid[maxn], id_clock;int maxw, ans[maxn];Pair seg[maxn<<2]; void input() { scanf( "%d%d", &n, &q ); for( int i=1,u,v; i<n; i++ ) { scanf( "%d%d", &u, &v ); g[u].push_back(v); g[v].push_back(u); }}void update( int w, int delta, int rt, int l, int r ) { if( l==r ) { seg[rt].val += delta; seg[rt].ind = l; return; } int mid = (l+r)>>1; if( mid>=w ) update( w, delta, lson, l, mid ); else update( w, delta, rson, mid+1, r ); seg[rt] = seg[lson].val < seg[rson].val ? seg[rson] : seg[lson];}void dfs1( int u ) { siz[u] = 1, son[u] = 0; for( int t=0; t<(int)g[u].size(); t++ ) { int v=g[u][t]; if( v==pre[u] ) continue; dep[v] = dep[u]+1; pre[v] = u; dfs1(v); siz[u] += siz[v]; son[u] = siz[v]>siz[son[u]] ? v : son[u]; }}void dfs2( int u, int tp ) { top[u] = tp, vid[u] = ++id_clock; if( son[u] ) dfs2( son[u], tp ); for( int t=0; t<(int)g[u].size(); t++ ) { int v=g[u][t]; if( v==pre[u] || v==son[u] ) continue; dfs2( v, v ); }}void build() { dep[1] = pre[1] = 1; dfs1(1); id_clock = 0; dfs2(1,1);}void modify( int u, int v, int w ) { while( top[u] != top[v] ) { if( dep[top[u]]<dep[top[v]] ) swap(u,v); flag[vid[top[u]]].push_back(w); flag[vid[u]+1].push_back(-w); u = pre[top[u]]; } if( dep[u]<dep[v] ) swap(u,v); flag[vid[v]].push_back(w); flag[vid[u]+1].push_back(-w);}void answer() { for( int i=1; i<=q; i++ ) { int u, v, w; scanf( "%d%d%d", &u, &v, &w ); modify( u, v, w ); maxw = max( maxw, w ); } for( int i=1; i<=id_clock; i++ ) { for( int t=0; t<(int)flag[i].size(); t++ ) { if( flag[i][t]>0 ) update( flag[i][t], 1, 1, 1, maxw ); if( flag[i][t]<0 ) update( -flag[i][t], -1, 1, 1, maxw ); } if( seg[1].val==0 ) ans[i] = 0; else ans[i] = seg[1].ind; } for( int i=1; i<=n; i++ ) printf( "%d\n", ans[vid[i]] );}int main() { input(); build(); answer();}void pv( vector<int> &v ) { for( int t=0; t<(int)v.size(); t++ ) fprintf( stderr, "%d ", v[t] ); fprintf( stderr, "\n" );}
(不懂为什么写一行空一行)
正确的标答
#include <iostream>#include <map>#define P(p) ((1)<<(p))#define MAXP 15using namespace std;int n, q;int head[100001], wght[100001], dest[200000], next[200000], etot;int table[200000][MAXP+1], deep[100001], posn[100001], prev[100001], stot, maxp;map<int,int> mp[100001];void insert( int a, int b ) { etot++; dest[etot] = b; next[etot] = head[a]; head[a] = etot;}void input() { ios::sync_with_stdio(false); cin>>n>>q; for( int i=1,a,b; i<n; i++ ) { cin>>a>>b; insert(a,b); insert(b,a); }}void dfst( int i, int f, int d ) { table[++stot][0] = i; posn[i] = stot; deep[i] = d; prev[i] = f; if( next[head[i]]==0 && dest[head[i]]==f ) return; for( int t=head[i]; t; t=next[t] ) { if( dest[t]==f ) continue; dfst(dest[t],i,d+1); table[++stot][0] = i; }}void makest() { dfst(1,1,1); for( maxp=MAXP; maxp>=0; maxp-- ) if( P(maxp)<stot ) break; for( int p=1; p<=maxp; p++ ) for( int i=1; stot-i+1>=P(p); i++ ) table[i][p] = deep[table[i][p-1]]<deep[table[i+P(p-1)][p-1]] ? table[i][p-1] : table[i+P(p-1)][p-1];}int lca( int u, int v ) { u = posn[u]; v = posn[v]; if( u>v ) swap(u,v); for( int p=maxp; p>=0; p-- ) if( P(p)<v-u+1 ) return deep[table[u][p]]<deep[table[v-P(p)+1][p]] ? table[u][p]:table[v-P(p)+1][p]; else if( P(p)==v-u+1 ) return table[u][p]; return 1<<31;}void dfs2( int i, int f ) { for( int t=head[i]; t; t=next[t] ) { if( dest[t]==f ) continue; dfs2(dest[t],i); } if( f==i ) return; for( map<int,int>::iterator it=mp[i].begin(); it!=mp[i].end(); it++ ) mp[f][it->first] += it->second;}void work() { makest(); while(q--) { int a, b, w, an; cin>>a>>b>>w; an = lca(a,b); mp[a][w]++; mp[b][w]++; mp[an][w]--; if( an!=1 ) mp[prev[an]][w]--; } dfs2(1,1); for( int i=1; i<=n; i++ ) { int xi=0, xv=0; for( map<int,int>::iterator it=mp[i].begin(); it!=mp[i].end(); it++ ) if( xv<it->second ) { xi = it->first; xv = it->second; } cout<<xi<<endl; }}int main() { freopen("rice.in","r",stdin); freopen("rice.out","w",stdout); input(); work();}
何神的标答
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<cctype>#include<algorithm>#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;#define smax(x,tmp) x=max((x),(tmp))#define smin(x,tmp) x=min((x),(tmp))#define maxx(x1,x2,x3) max(max(x1,x2),x3)#define minn(x1,x2,x3) min(min(x1,x2),x3)typedef long long LL;template <class T> inline void read(T &x){ x = 0; T flag = 1; char ch = (char)getchar(); while(ch<'0' || ch>'9') { if(ch == '-') flag = -1; ch = (char)getchar(); } while(ch>='0' && ch<='9') { x = (x<<1) + (x<<3) + ch - '0'; ch = (char)getchar(); } x *= flag;}template <class T> T gcd(T a,T b) { return !b?a:gcd(b,a%b); }// end templateconst int INF=0x3f3f3f3f;const int maxn = 100005;int n,q,Root,maxw;int ans[maxn];// original tree relatedstruct Edge{ int to,next;}edge[maxn<<1];int head[maxn];int maxedge;inline void addedge(int u,int v){ edge[++maxedge] = (Edge) { v,head[u] }; head[u] = maxedge; edge[++maxedge] = (Edge) { u,head[v] }; head[v] = maxedge;}// end original tree// LCA relatedconst int maxd = 18;const int D = 17;int fa[maxn][maxd];int depth[maxn];void lca(int u,int father,int deep){ depth[u] = deep; for(int k=1;k<=D;k++) fa[u][k] = fa[fa[u][k-1]][k-1]; for(int i=head[u];~i;i=edge[i].next) { int v = edge[i].to; if(v == father) continue; fa[v][0] = u; lca(v,u,deep+1); }}int LCA(int u,int v){ if(u == v) return u; if(depth[u] < depth[v]) swap(u,v); for(int k=D;k>=0;k--) if(depth[fa[u][k]] >= depth[v]) u = fa[u][k]; if(u == v) return u; for(int k=D;k>=0;k--) if(fa[u][k] ^ fa[v][k]) u = fa[u][k] , v = fa[v][k]; return fa[u][0];}// end LCA// segment tree relatedstruct Node{ int ch[2]; int pos,val; // the maxnode under this one and its value int size; // set for faster merge}node[maxn<<5];#define ch(x,d) node[x].ch[d]#define size(x) node[x].size#define pos(x) node[x].pos#define val(x) node[x].valint maxnode;int sta[maxn<<5],top;inline int require(){ int root; if(top) root = sta[top--]; else root = ++maxnode; return root;}void recycle(int &root){ if(!root) return; recycle(ch(root,0)); recycle(ch(root,1)); pos(root) = val(root) = 0; size(root) = 0; sta[++top] = root; root = 0;}inline void update(int root){ size(root) = size(ch(root,0)) + size(ch(root,1)); int lson = ch(root,0); int rson = ch(root,1); int rt = val(lson)>val(rson) || (val(lson)==val(rson)&&pos(lson)<pos(rson)) ? lson : rson; // the minimum type is required val(root) = val(rt); pos(root) = pos(rt);}void modify(int &root,int l,int r,int pos,int val){ if(!root) root = require(); if(l == r) { val(root) += val; pos(root) = l; size(root) = !!val(root); return; } int mid = (l+r)>>1; if(pos<=mid) modify(ch(root,0),l,mid,pos,val); else modify(ch(root,1),mid+1,r,pos,val); update(root);}void merge(int rt,int root,int l,int r){ if(!size(root)) return; if(l == r) { modify(rt,1,maxw,l,val(root)); return; } int mid = (l+r)>>1; merge(rt,ch(root,0),l,mid); merge(rt,ch(root,1),mid+1,r);}int ultra(int root1,int root2) // root2 to root1{ if(size(root1) < size(root2)) swap(root1,root2); merge(root1,root2,1,maxw); recycle(root2); return root1;}// end segment tree// delta relatedstruct Delta{ int next; int pos; int val;}delta[maxn<<2];int d_pre[maxn],d_post[maxn];int maxdelta;inline void addpre(int u,int pos,int val){ delta[++maxdelta] = (Delta) { d_pre[u],pos,val }; d_pre[u] = maxdelta;}inline void addpost(int u,int pos,int val){ delta[++maxdelta] = (Delta) { d_post[u],pos,val }; d_post[u] = maxdelta;}// end delta// maininline void init(){ memset(head,-1,sizeof(head)); maxedge=-1; memset(d_pre,-1,sizeof(d_pre)); memset(d_post,-1,sizeof(d_post)); maxdelta=-1; read(n); read(q); Root = (n+1)>>1; for(int i=1;i<n;i++) { int x,y; read(x); read(y); addedge(x,y); } lca(Root,-1,1);}void delta_composition(){ for(int i=1;i<=q;i++) { int x,y,w; read(x),read(y),read(w); smax(maxw,w); int the_lca = LCA(x,y); addpre(x,w,1); addpre(y,w,1); addpre(the_lca,w,-1); addpost(the_lca,w,-1); }}int dfs(int u,int father){ int root = require(); for(int i=head[u];~i;i=edge[i].next) { int v = edge[i].to; if(v == father) continue; root = ultra(dfs(v,u),root); } for(int i=d_pre[u];~i;i=delta[i].next) modify(root,1,maxw,delta[i].pos,delta[i].val); ans[u] = pos(root); for(int i=d_post[u];~i;i=delta[i].next) modify(root,1,maxw,delta[i].pos,delta[i].val); return root;}void work(){ dfs(Root,-1); for(int i=1;i<=n;i++) printf("%d\n",ans[i]);}int main(){ freopen("rice.in","r",stdin); freopen("rice.out","w",stdout); init(); delta_composition(); work(); return 0;}
综上所述,还是好好学习吧
GG
- 11月9日——离noip还有10天
- 11月8日——离noip还有11天
- 11月7日——离noip还有12天
- 11月13日——离noip还有6天【今天”认真“总结】
- 11月14日——离noip还有5天[Darker Than Black]
- 11月15日——离noip还有4天[Black Bullet]
- 11月16日——离noip还有3天[学战都市Asterisk]
- 11月17日——离noip还有2天[绯弹的亚里亚]
- 11月10日——离noip还有9天【你的名字……】与[一个神奇的函数]
- 11月11日——离noip还有8天【又是一年光棍节】[被狙击的学园]
- 11月12日——离noip还有7天[云之彼端,约定的地方]
- NOIP TEST Dyzerjet 10月29日
- 2014年9月5日还有两天中秋有感
- 11月30日——培训第9天
- 2013年9月9日--9月21日(有效时间7天,每天5小时,共35小时,还有5065小时)
- 2013年9月22日---2013年10月5日(每天1小时,共15小时,还有5050小时)
- 11月9日
- 11月9日
- laravel 自定义错误页面
- 商城分类页面自适应标题,自适应换行。
- linux安装nginx步骤
- gulp自动化ES6转ES5
- java中的Queue
- 11月9日——离noip还有10天
- SDP协议 会话描述协议
- You must rebuild it with bitcode enabled (Xcodesetting ENABLE_BITCODE), obtain an updated library f
- Scala的第一个程序
- 怎么把web项目发布到局域网,再发布到互联网
- 【caffe-Windows】mnist实例编译之model的使用-classification
- jsp画线
- CodeForces 712E
- 希拉里的退选演说