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

posted @ 2017-10-02 13:19  探险家Mr.H  阅读(185)  评论(0编辑  收藏  举报