这真的算NOIP?
我还是退役了吧
100+100+20
T1:看似水题,但是超时是很有可能的。
他是判断一个数是不是斐波拉切数列的前n项和
利用牛顿迭代可以一次求出sqrt然后向下取整判断
#include
#include
#include
#include
#include
#include
T2树形DP:HAOI2015树上染色
一个标准且典型的枚举边的代价
#include
#include
#include
#include
#include
using namespace std;
typedef int INT;
#define int long long
inline void read(int &x){
x=0;
char ch=getchar();
int f=1;
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=2100+1;
const int K=2100;
struct Front_star{
int u,v,w,nxt;
}e[N*3];
int cnt=1;
int first[N]={};
void add(int u,int v,int w){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].nxt=first[u];
first[u]=cnt;
}
int n,k;
int dp[N][K]={};
int siz[N]={};
int vis[N]={};
int getsiz(int u,int fat){
siz[u]=1;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(v==fat)continue;
siz[u]+=getsiz(v,u);
}
return siz[u];
}
void dfs(int u,int w){
// cout<=0;j--){
// cout<=remain;i--){
int wnow=w*(k-i)*i+w*(n-siz[u]-k+i)*(siz[u]-i);//left k-i right i
dp[u][i]=max(dp[u][i],dp[u][i-1])+wnow;
}
dp[u][0]+=w*(n-siz[u]-k)*(siz[u]);//left k right 0
}
INT main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
//cout<<"here";
read(n);
read(k);
for(int i=1;i
T3神仙题
看见割你需要想到对偶图
但是这有什么用
一个对偶图中的点选不上实际是边成环。
因为对偶图中的点是一个点块。
如果S,T在点块内那么他们都可以连通
否则不行
转化来到了:NOIP2017Day2T1
并查集判环(或者叫做判连通)
暴力代码:
#include
#include
#include
#include
#include
using namespace std;
//int idx[N][N]={};
inline void read(int &x){
x=0;
char ch=getchar();
int f=1;
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
const int N=51;
struct Front_star{
int u,v,nxt;
}e[N*N*2];
int cnt=1;
int first[N*N]={};
void add(int u,int v){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].nxt=first[u];
first[u]=cnt;
}
int idx[N][N];
int del[N*N][N*N]={};
int vis[N*N];
int n,k;
int lastans=1;
void dfs(int u,int goal){
vis[u]=1;
for(int i=first[u];i;i=e[i].nxt){
int v=e[i].v;
if(vis[v])continue;
if(del[u][v]||del[v][u])continue;
dfs(v,goal);
}
}
void check(int from,int goal){
// cout<<"in"<<'\n';
memset(vis,0,sizeof(vis));
vis[from]=1;
dfs(from,goal);
if(vis[goal]){
lastans=1;
}
else{
lastans=0;
}
if(lastans==1){
puts("TAK");
}
else{
puts("NIE");
}
}
int main(){
freopen("rain.in","r",stdin);
freopen("rain.out","w",stdout);
read(n);
read(k);
int idx_cnt=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
idx[i][j]=++idx_cnt;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i>1){
add(idx[i][j],idx[i-1][j]);
}
if(i1){
add(idx[i][j],idx[i][j-1]);
}
if(j
std
#include
#include
#include
#include
#include
using namespace std;
int n,k;
int idx[1505][1505]={};
int fa[1505*1505+10]={};
int idx_cnt=1;
int lastans=1;
//inline int getfa(int x){
// int a=x,c;
// while(x!=fa[x])x=fa[x];
// while(x!=(c=fa[a]))fa[a]=x,a=c;
// return x;
//}
int getfa(int x){
if(fa[x]==x)return x;
else return fa[x]=getfa(fa[x]);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i