20171001模拟赛
T1 poj2029
90分:二维前缀和
100分:二维树状数组维护二维前缀和(这叫什么满分算法啊喂)
反正瞎搞搞30minAC
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int T[10010][10010]; inline int lowbit(int x){return x&(-x);} int w,h,s,t,x,y; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();} while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();} return x*f; } inline int sum(int x,int y) { int res=0; for(int i=x;i>=1;i-=lowbit(i)) for(int j=y;j>=1;j-=lowbit(j))res+=T[i][j]; return res; } inline void update(int x,int y) { for(int i=x;i<=h;i+=lowbit(i)) for(int j=y;j<=w;j+=lowbit(j))T[i][j]++; } int main() { freopen("trees.in","r",stdin); freopen("trees.out","w",stdout); int n; while(~scanf("%d",&n) && n) { memset(T,0,sizeof(T)); w=read();h=read(); for(int i=1;i<=n;i++) { x=read(),y=read(); update(y,x); } int ans=-1; s=read(),t=read(); for(int i=t;i<=h;i++) for(int j=s;j<=w;j++) ans=max(ans,sum(i,j)+sum(i-t,j-s)-sum(i-t,j)-sum(i,j-s)); cout<<ans<<endl; } }
T2poj3250
高一轩同学出这道题的时候竟然把我当成了素材
真鸡儿刺激
把问题转化一下 题目问:“每个人能看到的人的总数”我们把它转换成“每个人能被看到的次数的总数”
于是打个单调递减栈 每插进来一个看栈里有多少元素就行了
强烈鄙视yyc的做法
因为我竟然不会
淦
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; int st[80010],top,n,h,ans; int main() { freopen("height.in","r",stdin); freopen("height.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&h); while(top>0 && st[top-1]<=h)--top; ans+=top; st[top++]=h; } cout<<ans; }
T3bzoj1924
这题一看
有向图最长链
又一看
mmp邻接矩阵邻接表全**开不下
于是想到Tarjan缩点
于是差不多就解决了
横门和横门之间连无向边 和其他连有向边
竖门同理
周围8格用map存一下联通连边
Tarjan
Dp
完事
70
为什么只有70 因为满分只有70呀
淦 没开O2 我的mapT掉了
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<map> #include<vector> using namespace std; const int maxn=1000100; const int dx[]={0,0,1,1,1,-1,-1,-1}; const int dy[]={1,-1,0,1,-1,0,1,-1}; inline int read() { int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();} while(isdigit(ch)){x=10*x+ch-'0';ch=getchar();} return x*f; } struct edge { int to,next; }e1[maxn],e2[maxn]; int k,m,n; int cnt,first1[maxn],first2[maxn]; int dfn[maxn],low[maxn],bl[maxn],scc,ind,mark[maxn],q[maxn],num[maxn],top; int deep[maxn]; int x[maxn],y[maxn],t[maxn]; vector<int> a[maxn],b[maxn]; map<int,int> mp[maxn]; int ans; inline void add(int u,int v) { e1[++cnt].to=v; e1[cnt].next=first1[u]; first1[u]=cnt; } inline void Add(int u,int v) { e2[++cnt].to=v; e2[cnt].next=first2[u]; first2[u]=cnt; } void tarjan(int x) { low[x]=dfn[x]=++ind; q[++top]=x;mark[x]=1; for(int i=first1[x];i;i=e1[i].next) { if(!dfn[e1[i].to]) { tarjan(e1[i].to); low[x]=min(low[x],low[e1[i].to]); } else if(mark[e1[i].to]) low[x]=min(low[x],dfn[e1[i].to]); } if(low[x]==dfn[x]) { int now=0;scc++; while(now!=x) { now=q[top--];mark[now]=0; bl[now]=scc;num[scc]++; } } } void dp(int x) { mark[x]=1; for(int i=first2[x];i;i=e2[i].next) { if(!mark[e2[i].to])dp(e2[i].to); deep[x]=max(deep[x],deep[e2[i].to]); } deep[x]+=num[x]; ans=max(ans,deep[x]); } int main() { freopen("soto.in","r",stdin); freopen("soto.out","w",stdout); k=read(),n=read(),m=read(); for(int i=1;i<=k;i++) { x[i]=read(),y[i]=read(),t[i]=read(); mp[x[i]][y[i]]=i; a[x[i]].push_back(i); b[y[i]].push_back(i); } for(int i=1;i<=n;i++) { int x=0,sz=a[i].size(); for(int j=0;j<sz;j++) if(t[a[i][j]]==1){x=a[i][j];break;} for(int j=0;j<sz;j++) { add(x,a[i][j]); if(t[a[i][j]]==1)add(a[i][j],x); } } for(int i=1;i<=m;i++) { int x=0,sz=b[i].size(); for(int j=0;j<sz;j++) if(t[b[i][j]]==2){x=b[i][j];break;} for(int j=0;j<sz;j++) { add(x,b[i][j]); if(t[b[i][j]]==2)add(b[i][j],x); } } for(int i=1;i<=k;i++) if(t[i]==3) for(int j=0;j<8;j++) { int re=mp[x[i]+dx[j]][y[i]+dy[j]]; if(re)add(i,re); } for(int i=1;i<=k;i++) if(!dfn[i])tarjan(i); cnt=0; for(int x=1;x<=k;x++) for(int i=first1[x];i;i=e1[i].next) if(bl[x]!=bl[e1[i].to])Add(bl[x],bl[e1[i].to]); for(int i=1;i<=scc;i++) if(!mark[i])dp(i); cout<<ans; return 0; }
D1270