标签:sse lowbit eof 应该 time clock lock get href
Claris大爷出的一套模拟题。问别人要到了一份题,加深了自己NOIp要滚粗的感觉。
zzDP题,我只能说我第一遍写的时候还写崩了QAQ。
//master
//by Cydiater
//2016.10.21
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define FILE "master"
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
const int MAXN=305;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
int N,K,f[MAXN][MAXN][MAXN][2];
char s1[MAXN],s2[MAXN];
namespace solution{
void init(){
N=read();K=read();
scanf("%s",s1+1);
scanf("%s",s2+1);
}
void DP(){
memset(f,0,sizeof(f));
up(i,1,N)up(j,1,N)up(k,0,K){
f[i][j][k][0]=max(f[i][j-1][k][0],f[i-1][j][k][0]);
if(k>0)cmax(f[i][j][k][1],f[i-1][j-1][k-1][1]+1);
if(s1[i]==s2[j]){
cmax(f[i][j][k][1],f[i-1][j-1][k][1]+1);
}
cmax(f[i][j][k][0],f[i][j][k][1]);
}
}
void output(){
cout<<f[N][N][K][0]<<endl;
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
init();
DP();
output();
return 0;
}
通过这道题学到了bitset的简单用法,很实用。
那道题的时候想了想搞到了70分的做法,卡在了如何$O(1)$求三元环的算法上,事实证明不一定要$O(1)$,用bitset小优化一下就行了。
这道题充分说明了降维思想的重要性。
//tour
//by Cydiater
//2016.10.21
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <ctime>
#include <cmath>
#include <iomanip>
#include <cstdlib>
#include <bitset>
#include <cstdio>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define FILE "tour"
#define LENGTH 1500
#define bs bitset<LENGTH>
const int MAXN=1505;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
int N,LEN,cnt[MAXN];
bool mat[MAXN][MAXN];
char s[MAXN];
ll ans=0;
struct BITSET{
bs v;
}Match[MAXN];
namespace solution{
inline int lowbit(int i){return i&(-i);}
void init(){
N=read();LEN=(N-1)/LENGTH+1;
memset(cnt,0,sizeof(cnt));
up(i,1,N){
scanf("%s",s+1);
up(j,1,N)if((mat[i][j]=s[j]-‘0‘)==1)cnt[i]++;
int now=1;
up(j,1,LEN){
bs S(0),tmp;
up(k,now,min(N,now+LENGTH-1))
if(mat[i][k])
Match[i].v[k-now]=1;;
now+=LENGTH;
}
}
}
int get(int x,int y){
return (Match[x].v&Match[y].v).count();
}
void slove(){
up(i,1,N)up(j,i+1,N)if(i!=j&&mat[i][j]){
ans+=(ll)(cnt[i]-1)*(ll)(cnt[j]-1)*2LL;
ans-=get(i,j)*2LL;
}
}
void output(){
cout<<ans<<endl;
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
init();
slove();
output();
//cout<<"Time has passed:"<<1.0*clock()/1000<<"s!"<<endl;
return 0;
}
做的时候最没有头绪的一道题。需要在原图上加点建立一个新图,新建的分别代表$[0,2^{20}-1]$上的每一个点,然后每个点向其二进制下有且只要以为不为1的连边,然后对于原图上的每个点,指向对应的新点一条边权为1的边,然后反向连一条边权为0的边。然后大力BFS,需要注意的是每次应该把所有与其距离为0的都加入队列中。
//walk
//by Cydiater
//2016.10.23
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <bitset>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <ctime>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define FILE "walk"
const int MAXN=2e6+5;
const int oo=0x3f3f3f3f;
inline int read(){
char ch=getchar();int x=0,f=1;
while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
return x*f;
}
int N,M,V[1300000],LINK[1300000],len=0,head,tail,q[1300000],dis[1300000];
bool vis[1300000];
struct edge{
int y,next,v;
}e[MAXN*10];
namespace solution{
inline void insert(int x,int y,int v){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].v=v;}
void init(){
N=read();M=read();
up(i,1,N)V[i]=read();
up(i,1,M){
int x=read(),y=read();
insert(x,y,1);
}
up(i,0,(1<<20)-1){
up(j,0,19)if(((1<<j)&(i))==(1<<j)){
int x=i,y=i^(1<<j);
insert(N+1+x,N+1+y,0);
}
}
up(i,1,N){
insert(i,N+1+V[i],1);
insert(N+1+V[i],i,0);
}
}
void ADD(int node){
q[++tail]=node;vis[node]=1;
for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]&&!e[i].v){
dis[e[i].y]=dis[node];
ADD(e[i].y);
}
}
void slove(){
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
head=1;tail=0;q[++tail]=1;
dis[1]=0;vis[1]=1;
for(;head<=tail;head++){
int node=q[head];
for(int i=LINK[node];i;i=e[i].next)if(!vis[e[i].y]){
dis[e[i].y]=dis[node]+e[i].v;
ADD(e[i].y);
}
}
up(i,2,N)if(dis[i]==0)dis[i]=-1;
}
void output(){
up(i,1,N)printf("%d\n",dis[i]);
}
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
init();
slove();
output();
return 0;
}
标签:sse lowbit eof 应该 time clock lock get href
原文地址:http://www.cnblogs.com/Cydiater/p/5989107.html