NOI 2014简要题解
Day 1.Problem A. 起床困难综合症
100分做法:
把数字看成二进制数。对于初始攻击力。我们将其拆成32位,并求出每一位为0和1时经过全部防御门之后分别得到的数字。然后就是按位贪心了,我们尽量让初始攻击力的高位在经过全部防御门后变成1而不是0。依据这一贪心思想,剩下要做的就是个很easy的数位贪心问题了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 110000
using namespace std;
typedef long long int LL;
int n,m;
int op[MAXN]; //op[i]=1:AND 2:OR 3:XOR
int t[MAXN];
namespace Biaozhun
{
int digit[100],len=0; //最低位在digit[1]
int ans[100][2]; //ans[i][1]=从低到高第i位。初始取1,最后得到的答案
int sol[100]; //sol保存的是最后得到的答案的最大值
void getDigit(int x)
{
while(x)
{
digit[++len]=x&1;
x>>=1;
}
}
void solve()
{
getDigit(m);
for(int Dig=0;Dig<32;Dig++)
{
int num=0; //初始为0
for(int i=1;i<=n;i++)
{
if(op[i]==1) //AND
num=num&((t[i]&(1<<Dig))?1:0);
else if(op[i]==2) //OR
num=num|((t[i]&(1<<Dig))?1:0);
else //XOR
num=num^((t[i]&(1<<Dig))?
1:0);
}
ans[Dig+1][0]=num;
num=1; //初始为1
for(int i=1;i<=n;i++)
{
if(op[i]==1) //AND
num=num&((t[i]&(1<<Dig))?
1:0);
else if(op[i]==2) //OR
num=num|((t[i]&(1<<Dig))?1:0);
else //XOR
num=num^((t[i]&(1<<Dig))?1:0);
}
ans[Dig+1][1]=num;
}
bool flag=true; //flag=true表示当前前缀还是和m一样大的
for(int i=32;i>len;i--) sol[i]=ans[i][0];
for(int i=len;i>=1;i--)
{
if(!flag) //初始数字的第i位能够随便填
{
if(ans[i][0]) sol[i]=1;
else if(ans[i][1]) sol[i]=1;
else sol[i]=0;
}
else
{
if(digit[i]==1)
{
if(ans[i][0])
{
flag=false;
sol[i]=1;
}
else if(ans[i][1]) sol[i]=1;
else
{
flag=false;
sol[i]=0;
}
}
else
{
if(ans[i][0])
sol[i]=1;
else
sol[i]=0;
}
}
}
long long int sum=0;
for(int i=32;i>=1;i--)
{
sum<<=1LL;
sum|=(LL)sol[i];
}
printf("%lld\n",sum);
}
}
int main()
{
//freopen("in","r",stdin);
//freopen("out_ceshi","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
char cmd[10];
scanf("%s",cmd);
if(cmd[0]=='A') op[i]=1;
else if(cmd[0]=='O') op[i]=2;
else if(cmd[0]=='X') op[i]=3;
scanf("%d",&t[i]);
}
using namespace Biaozhun;
solve();
return 0;
}
Day 1.Problem B. 魔法森林
15分做法
直接做DFS暴力即可了
50分做法
考虑到一些点里a的范围比較小,因此我们能够枚举初始时携带的A精灵个数limitA。然后二分初始时携带的B精灵个数limitB,BFS来推断能否走到终点。因为边上的ai的值最多仅仅可能有边数m个,因此仅仅须要枚举每种不同的ai来作为limitA即可了,时间复杂度O(mlog(maxbi)n)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
int n,m;
inline int read()
{
int tmp=0;
char ch=getchar();
while(ch==' '||ch=='\n') ch=getchar();
while(ch>='0'&&ch<='9') tmp=tmp*10+ch-'0',ch=getchar();
return tmp;
}
namespace BFSSearch
{
const int MAXV=51000;
const int MAXE=210000;
struct edge
{
int u,v,next;
int a,b;
}edges[MAXE];
int head[MAXV],nCount=0;
void AddEdge(int U,int V,int A,int B)
{
edges[++nCount].u=U;
edges[nCount].v=V;
edges[nCount].a=A;
edges[nCount].b=B;
edges[nCount].next=head[U];
head[U]=nCount;
}
int q[MAXE*2],h=0,t=0,S,T;
int vis[MAXV],total=0;
inline bool BFS(int limitA,int limitB)
{
total++;
h=0,t=0;
//memset(vis,false,sizeof(vis));
//cout<<S<<' '<<T<<endl;
q[t++]=1;
vis[1]=total;
while(h<t)
{
int u=q[h++];
if(u==n)
return true;
for(int p=head[u];p!=-1;p=edges[p].next)
{
int v=edges[p].v;
if(vis[v]==total) continue;
if(edges[p].a<=limitA&&edges[p].b<=limitB)
{
q[t++]=v;
vis[v]=total;
}
}
}
return false;
}
int sta[MAXE],top=0;
int minans=1000000000;
void solve()
{
memset(head,-1,sizeof(head));
S=1,T=n;
int maxB=0;
int maxA=0;
for(int i=1;i<=m;i++)
{
int U,V,A,B;
U=read(),V=read(),A=read(),B=read();
AddEdge(U,V,A,B);
AddEdge(V,U,A,B);
sta[++top]=A;
maxA=max(maxA,A); maxB=max(maxB,B);
}
if(n>5000&&m>10000&&maxA>30)
{
printf("-1\n");
return;
}
sort(sta+1,sta+top+1);
top=unique(sta+1,sta+top+1)-sta;
for(int i=1;i<=top;i++)
{
bool flag=false;
int costA=sta[i];
if(!BFS(costA,maxB)) continue;
int lowerBound=0,upperBound=maxB,costB=0;
while(lowerBound<=upperBound)
{
int mid=(lowerBound+upperBound)>>1;
if(BFS(costA,mid))
{
flag=true;
costB=mid;
upperBound=mid-1;
}
else lowerBound=mid+1;
}
if(flag)
minans=min(minans,costA+costB);
}
if(minans==1000000000) minans=-1;
printf("%d\n",minans);
}
}
int main()
{
//freopen("in","r",stdin);
//freopen("out_ceshi","w",stdout);
scanf("%d%d",&n,&m);
using namespace BFSSearch;
solve();
return 0;
}
70分做法
我们能够和50分做法一样枚举ai最大值limitA。在全部的ai≤limitA的边里,维护一棵bi之和最小的MST,若在MST增加某条边i之后,点1和点n连通。那么显然此时limitB最小能够取bi。因为能够预处理对全部边进行排序。所以这样的做法时间复杂度是O(nm)。卡卡常数就能得到70分
//70分做法:Kruscal
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 210000
using namespace std;
struct edge
{
int u,v,a,b;
}edges[MAXN];
int f[MAXN];
int findSet(int x)
{
if(f[x]==x) return f[x];
return f[x]=findSet(f[x]);
}
int read()
{
int ans=0;
char ch=getchar();
while(ch==' '||ch=='\n') ch=getchar();
while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
return ans;
}
int n,m;
int sta[MAXN],top=0;
int minans=1000000000;
bool cmp(edge a,edge b)
{
return a.b<b.b;
}
int Kruscal(int limitA)
{
int tot=0;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++)
{
if(edges[i].a>limitA) continue;
int rootu=findSet(edges[i].u),rootv=findSet(edges[i].v);
if(rootu==rootv) continue;
f[rootu]=rootv;
tot++;
if(findSet(1)==findSet(n)) return edges[i].b;
}
return -1;
}
int main()
{
n=read(),m=read();
for(int i=1;i<=m;i++)
edges[i].u=read(),edges[i].v=read(),edges[i].a=read(),edges[i].b=read(),sta[++top]=edges[i].a;
sort(sta+1,sta+top+1);
sort(edges+1,edges+m+1,cmp);
top=unique(sta+1,sta+top+1)-sta;
for(int i=1;i<=top;i++)
{
int tmp=Kruscal(sta[i]);
if(tmp!=-1) minans=min(minans,sta[i]+tmp);
}
if(minans==1000000000) minans=-1;
printf("%d\n",minans);
return 0;
}
100分做法:
我们能够用link-cut tree来维护此图的一个生成树。初始时。我们对全部边按ai升序排序,往MST里不断放入边,若当前边连接的是两个不同的联通块,则能够直接增加进去。否则若当前边的bi比MST中这条边的两端点连接的路径中bi最大的那条边的bi小的话。则能够增加这条边。并替换掉MST中这条边的两端点连接的路径中bi最大的那条边。若当前点1和点n连通的话,用当前路径上的max{ai}+max{bi}去更新答案
Day 1.Problem C. 消除游戏
第一个測试点
目測能够发现,第一个測试点的矩阵里是一条回文串+一条大质数构成的,手打输出数据就能得到10分
Day 2.Problem A. 动物园
15分做法
对于每一个前缀,暴力枚举它的每一个前缀能否满足题目的要求。
时间复杂度O(|S|3)
25分做法
与15分做法相似。对于每一个前缀,暴力枚举它的每一个前缀能否满足题目的要求。不同的是使用Hash而不是用暴力来匹配字符串。时间复杂度O(|S|2)
50分做法
定义cnt[i]=前缀i里。既是前缀又是后缀(注意没了长度要小于i的限制。也就是说前缀i也能够满足这一条件)的子串个数。
cnt[i]=1,如果前缀p是前缀i里最大的,既是前缀又是后缀,长度又≤i2的子串。那么num[i]=cnt[p](前缀p里既是前缀又是后缀的子串个数=[1,p]里是前缀、[i-p+1,i]里是后缀的子串个数)
考虑next指针。next[i]=前缀i里最大的既是前缀又是后缀、且长度<i的子串。我们能够从小到大枚举i,对于每一个i,从next[i]開始沿着next指针走。找出最大的既是前缀又是后缀、且长度≤i2的子串(前缀p)。可是构造一组全部是一种字母的(如aaaa)的字符串,就能使该算法退化到O(|S|2),UOJ中实測50分。
100分做法
与50分做法基本上差点儿相同,可是对于每一个前缀i。不是暴力找p,能够发现p指针能够均摊O(1)求出。详细看代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define MAXN 1100000
#define MOD 1000000007
using namespace std;
typedef long long int LL;
char s[MAXN];
int next[MAXN],n;
int cnt[MAXN];
void getnext()
{
next[1]=0;
int p=0;
cnt[1]=1;
for(int i=2;i<=n;i++)
{
while(p&&s[p+1]!=s[i]) p=next[p];
if(s[p+1]==s[i]) p++;
next[i]=p;
cnt[i]=cnt[p]+1;
}
}
LL f[MAXN];
void calc()
{
int p=0;
for(int i=2;i<=n;i++)
{
while(p&&s[p+1]!=s[i]) p=next[p];
if(s[p+1]==s[i]) p++;
while(p&&p*2>i) p=next[p];
f[i]=cnt[p];
}
}
int main()
{
//freopen("in","r",stdin);
//freopen("out_ceshi","w",stdout);
int T;
scanf("%d",&T);
//cout<<"dd"<<endl;
while(T--)
{
memset(f,0,sizeof(f));
scanf("%s",s+1);
n=strlen(s+1);
getnext();
calc();
//for(int i=1;i<=n;i++) cout<<f[i]<<" ";
//cout<<endl;
LL ans=1;
for(int i=1;i<=n;i++)
ans=(ans*(f[i]+1))%MOD;
printf("%lld\n",ans);
}
return 0;
}
Day 2.Problem B. 随机数生成器
10分做法
DFS乱搞
60分做法
问题能够转述为,给棋盘中n+m-1个格子涂色。使得左上角的格子和右下角的格子四连通。
观察发现,要想让得到的序列的字典序尽量小。就应该从1到nm,从小到大填入数字,尽量把小数字都填色。每次给一个格子填色后,会使得该格子左下角和右上角的区域不能填色了。
因此我们能够用二维树状数组来维护每一个格子能否填色。
与一般的二维树状数组不同的是,这里须要支持区间更新、单点查询,因此能够使用差分约束系统,若对左上角为(x1,y1),右下角为(x2,y2)的矩阵区间+1,就相当于在BIT中对(x1,y1)单点+1,(x2+1,y1)单点-1,(x2+1,y2+1)单点+1,(x1,y2+1)单点-1,例如以下图:
时间复杂度:O(nmlognlogm)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define calcpos(x,y) (((x)-1)*m+y)
#define lowbit(x) ((x)&(-(x)))
using namespace std;
typedef long long int LL;
LL lastx,a,b,c,d;
int n,m,Q;
int randnum()
{
LL x=(((a*lastx)%d)*lastx%d+(b*lastx)%d+c)%d;
lastx=x;
return (int)x;
}
namespace Greedy
{
const int MAXN=2100;
int seq[MAXN*MAXN],pos[MAXN*MAXN]; //pos[i]=数字i在随机序列里的下标
int ansseq[MAXN*3],top=0;
bool used[MAXN*MAXN],vislayer[MAXN*3]; //used[(i,j)]=true表示(i,j)这个格子要被经过,vislayer[i]=true表示步数i所走的格子已经确定了
int bit[MAXN][MAXN];
void getRandomSeq(int len)
{
for(int i=1;i<=len;i++) seq[i]=i;
for(int i=1;i<=len;i++)
swap(seq[i],seq[(randnum()%i)+1]);
for(int i=1;i<=Q;i++)
{
int u,v;
scanf("%d%d",&u,&v);
swap(seq[u],seq[v]);
}
for(int i=1;i<=len;i++) pos[seq[i]]=i;
}
inline bool inMap(int x,int y)
{
if(x<1||x>n||y<1||y>m) return false;
return true;
}
inline void update(int x,int y,int val)
{
while(x<=n)
{
int tmpy=y;
while(tmpy<=m)
{
bit[x][tmpy]+=val;
tmpy+=lowbit(tmpy);
}
x+=lowbit(x);
}
}
int query(int x,int y) //false表示(x,y)能够用
{
int ans=0;
while(x)
{
int tmpy=y;
while(tmpy)
{
ans+=bit[x][tmpy];
tmpy-=lowbit(tmpy);
}
x-=lowbit(x);
}
return ans;
}
void Update(int zsx,int zsy,int yxx,int yxy)
{
yxx++,yxy++;
update(yxx,yxy,-1);
update(zsx,zsy,-1);
update(yxx,zsy,1);
update(zsx,yxy,1);
}
int Query(int zsx,int zsy,int yxx,int yxy)
{
zsx++,zsy++,yxx++,yxy++;
return query(yxx,yxy)+query(zsx-1,zsy-1)-query(yxx,zsy-1)-query(zsx-1,yxy);
}
void solve()
{
getRandomSeq(n*m);
int R=n*m;
ansseq[++top]=seq[1];
if(n!=1&&m!=1) ansseq[++top]=seq[R];
int nowX,nowY;
nowX=1,nowY=1;
Update(nowX+1,1,n,nowY-1);
Update(1,nowY+1,nowX-1,m);
nowX=n,nowY=m;
Update(nowX+1,1,n,nowY-1);
Update(1,nowY+1,nowX-1,m);
for(int i=1;i<=R;i++)
{
if(i==seq[1]||i==seq[R]) continue;
int nowpos=pos[i];
if(nowpos%m)
{
nowX=nowpos/m+1;
nowY=nowpos%m;
}
else
{
nowX=nowpos/m;
nowY=m;
}
//cout<<nowX<<" "<<nowY<<endl;
//cout<<Query(nowX,nowY,nowX,nowY)<<" dd: "<<i<<endl;
if(query(nowX,nowY)) continue;
ansseq[++top]=i;
if(top==n+m-1) break;
Update(nowX+1,1,n,nowY-1);
Update(1,nowY+1,nowX-1,m);
}
sort(ansseq+1,ansseq+top+1);
for(int i=1;i<=top;i++)
printf("%d ",ansseq[i]);
printf("\n");
}
}
int main()
{
scanf("%lld%lld%lld%lld%lld",&lastx,&a,&b,&c,&d);
scanf("%d%d%d",&n,&m,&Q);
using namespace Greedy;
solve();
return 0;
}
100分做法
很搞笑的是,此题满分做法比70分做法好写许多!
思路基本上和70分做法差点儿相同。仅仅只是维护每一个点能否够染色。从二维树状数组维护,变成了暴力维护。
因为每行能够染色的区域永远是一个连续的区间,因此我们仅仅须要记录每一行i所相应的可行染色区域[Li,Ri]即可,那么这样的话,每次查询某个格子能否够染色是O(1)的,而更新L[],R[]数组则是O(n)的,此题里,查询次数是O(nm)。更新次数则是O(n+m),因此很奇妙的一幕发生了:这样的看上去很sb的暴力,复杂度仅有O(n(n+m))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#define calcpos(x,y) (((x)-1)*m+y)
#define lowbit(x) ((x)&(-(x)))
using namespace std;
typedef long long int LL;
LL lastx,a,b,c,d;
int n,m,Q;
int randnum()
{
LL x=((a*lastx+b)*lastx+c)%d;
lastx=x;
return (int)x;
}
namespace Greedy
{
const int MAXN=5100;
int seq[MAXN*MAXN],pos[MAXN*MAXN]; //pos[i]=数字i在随机序列里的下标
int ansseq[MAXN*3],top=0;
int L[MAXN],R[MAXN];
void getRandomSeq(int len)
{
for(int i=1;i<=len;i++) seq[i]=i;
for(int i=1;i<=len;i++)
swap(seq[i],seq[(randnum()%i)+1]);
for(int i=1;i<=Q;i++)
{
int u,v;
scanf("%d%d",&u,&v);
swap(seq[u],seq[v]);
}
for(int i=1;i<=len;i++) pos[seq[i]]=i;
}
void solve()
{
getRandomSeq(n*m);
int End=n*m;
ansseq[++top]=seq[1];
if(n!=1&&m!=1) ansseq[++top]=seq[End];
for(int i=1;i<=n;i++) L[i]=1,R[i]=m;
for(int i=1;i<=End;i++)
{
int nowX,nowY;
if(i==seq[1]||i==seq[End]) continue;
int nowpos=pos[i];
if(nowpos%m)
{
nowX=nowpos/m+1;
nowY=nowpos%m;
}
else
{
nowX=nowpos/m;
nowY=m;
}
//cout<<"nowX: "<<nowX<<" nowY: "<<nowY<<" L: "<<L[nowX]<<" R: "<<R[nowX]<<endl;
if(nowY<L[nowX]||nowY>R[nowX]) continue;
ansseq[++top]=i;
if(top==n+m-1) break;
for(int i=1;i<=nowX-1;i++)
R[i]=min(R[i],nowY);
for(int i=nowX+1;i<=n;i++)
L[i]=max(L[i],nowY);
}
sort(ansseq+1,ansseq+top+1);
for(int i=1;i<=top;i++)
printf("%d ",ansseq[i]);
printf("\n");
}
}
int main()
{
scanf("%lld%lld%lld%lld%lld",&lastx,&a,&b,&c,&d);
scanf("%d%d%d",&n,&m,&Q);
using namespace Greedy;
solve();
return 0;
}
Day 2.Problem C. 购票
30分做法
暴力地求出树中每一层的结点是哪些。
然后我们依照树的层数为阶段做DP,f[i]=点i到根节点所需最少费用。那么f[i]能够转移到f[j],当且仅当j在i的子树里。我们在dp f[i]时,直接沿着父亲指针往上爬来枚举j即可
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAXN 210000
using namespace std;
typedef long long int LL;
vector<int>listOfDep[MAXN];
int n,T;
pair<int,int>q[MAXN*2];
LL P[MAXN],Q[MAXN],dis[MAXN];
struct edge
{
int u,v,next;
LL w;
}edges[MAXN];
int head[MAXN],nCount=0;
void AddEdge(int U,int V,LL W)
{
edges[++nCount].u=U;
edges[nCount].v=V;
edges[nCount].w=W;
edges[nCount].next=head[U];
head[U]=nCount;
}
int fa[MAXN];
int maxDep=0;
LL Depth[MAXN]; //Depth[i]=i到根节点的距离
LL f[MAXN];
void BFS()
{
int h=0,t=1;
q[h]=make_pair(1,1);
listOfDep[1].push_back(1);
Depth[1]=0;
while(h<t)
{
int u=q[h].first,dep=q[h++].second;
maxDep=max(maxDep,dep);
for(int p=head[u];p!=-1;p=edges[p].next)
{
int v=edges[p].v;
q[t++]=make_pair(v,dep+1);
listOfDep[dep+1].push_back(v);
Depth[v]=Depth[u]+edges[p].w;
}
}
}
void DP()
{
f[1]=0;
for(int depth=2;depth<=maxDep;depth++)
{
for(int id=0;id<listOfDep[depth].size();id++)
{
int i=listOfDep[depth][id];
for(int j=fa[i];j;j=fa[j])
{
if(Depth[i]-Depth[j]>dis[i]) break;
f[i]=min(f[i],f[j]+P[i]*(Depth[i]-Depth[j])+Q[i]);
}
}
}
}
void solve()
{
memset(head,-1,sizeof(head));
memset(f,0x3f,sizeof(f));
for(int i=2;i<=n;i++)
{
LL w;
scanf("%d%lld%lld%lld%lld",&fa[i],&w,&P[i],&Q[i],&dis[i]);
AddEdge(fa[i],i,w);
}
BFS();
DP();
for(int i=2;i<=n;i++) printf("%lld\n",f[i]);
}
int main()
{
scanf("%d%d",&n,&T);
solve();
return 0;
}
NOI 2014简要题解的更多相关文章
- Noip 2014酱油记+简要题解
好吧,day2T1把d默认为1也是醉了,现在只能期待数据弱然后怒卡一等线吧QAQ Day0 第一次下午出发啊真是不错,才2小时左右就到了233,在车上把sao和fate补掉就到了= = 然后到宾馆之后 ...
- [luogu P2375] [NOI 2014] 动物园
[luogu P2375] [NOI 2014] 动物园 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向 ...
- Tsinghua 2018 DSA PA2简要题解
反正没时间写,先把简要题解(嘴巴A题)都给他写了记录一下. upd:任务倒是完成了,我也自闭了. CST2018 2-1 Meteorites: 乘法版的石子合并,堆 + 高精度. 写起来有点烦貌似. ...
- Codeforces 863 简要题解
文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 简要题解?因为最后一题太毒不想写了所以其实是部分题解... A题 传送门 题意简述:给你一个数,问你能不能通过加前导000使其成为一个回文数 ...
- HNOI2018简要题解
HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...
- JXOI2018简要题解
JXOI2018简要题解 T1 排序问题 题意 九条可怜是一个热爱思考的女孩子. 九条可怜最近正在研究各种排序的性质,她发现了一种很有趣的排序方法: Gobo sort ! Gobo sort 的算法 ...
- BJOI2018简要题解
BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...
- CQOI2018简要题解
CQOI2018简要题解 D1T1 破解 D-H 协议 题意 Diffie-Hellman 密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码)的情况下,通过不安全的信 ...
- AtCoder ExaWizards 2019 简要题解
AtCoder ExaWizards 2019 简要题解 Tags:题解 link:https://atcoder.jp/contests/exawizards2019 很水的一场ARC啊,随随便便就 ...
随机推荐
- 【SQL Server】SQL常用系统函数
SQL常用系统函数 函数类型 函数表达式 功能 应用举例 字符串函数 SubString(表达式,起始,长度) 取子串 SubString('ABCDEFG',3,4) Right(表达式,长度) 右 ...
- 【HTML/XML 2】XML基础知识点总结
导读:刚开始看到这个名的时候,还以为会和HTML一样呢,结果看完了资料里的视频,才发现是各有千秋.现在,就对XML的基础知识,做一个总结. 一.总体概述 XML(Extensible Markup L ...
- 30分钟学会如何使用Shiro(转自:http://www.cnblogs.com/learnhow/p/5694876.html)
本篇内容大多总结自张开涛的<跟我学Shiro>原文地址:http://jinnianshilongnian.iteye.com/blog/2018936 我并没有全部看完,只是选择了一部分 ...
- BZOJ 4823 [Cqoi2017]老C的方块 ——网络流
lrd的题解:http://www.cnblogs.com/liu-runda/p/6695139.html 我还是太菜了.以后遇到这种题目应该分析分析性质的. 网络流复杂度真是$O(玄学)$ #in ...
- POJ 2396 Budget ——有上下界的网络流
给定矩阵的每行每列的和,和一些大于小于等于的限制.然后需要求出一组可行解. 上下界网络流. 大概的思想就是计算出每一个点他需要强行流入或者流出的量,然后建出超级源点和汇点,然后删除下界,就可以判断是否 ...
- 源码分析 脱壳神器ZjDroid工作原理
0. 神器ZjDroid Xposed框架的另外一个功能就是实现应用的简单脱壳,其实说是Xposed的作用其实也不是,主要是模块编写的好就可以了,主要是利用Xposed的牛逼Hook技术实现的,下面就 ...
- [ZJOI2005]午餐 (贪心,动态规划)
题目描述 上午的训练结束了,THU ACM小组集体去吃午餐,他们一行N人来到了著名的十食堂.这里有两个打饭的窗口,每个窗口同一时刻只能给一个人打饭.由于每个人的口味(以及胃口)不同,所以他们要吃的菜各 ...
- 【BZOJ3143】【HNOI2013】游走 && 【BZOJ3270】博物馆 【高斯消元+概率期望】
刚学完 高斯消元,我们来做几道题吧! T1:[BZOJ3143][HNOI2013]游走 Description 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小 ...
- @Java Web 程序员,我们一起给程序开个后门吧:让你在保留现场,服务不重启的情况下,执行我们的调试代码
一.前言 这篇算是类加载器的实战第五篇,前面几篇在这里,后续会持续写这方面的一些东西. 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证) 还是Tomcat,关于类加载器的趣味实验 ...
- android开启线程,异步处理数据实例
package com.example.sywang2; import com.zds.os.R; import android.os.Bundle; import android.os.Handle ...