第二周 5.24-5.30

5.24

 

2015百度之星资格赛 1003 IP聚合

水。数据小。暴解即可。

STL依赖症。set需重载<

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <set>

 4 using namespace std;

 5 

 6 struct node

 7 {

 8     int a,b,c,d;

 9     friend bool operator < (node X,node Y)

10     {

11         if(X.a!=Y.a) return X.a<Y.a;

12         if(X.b!=Y.b) return X.b<Y.b;

13         if(X.c!=Y.c) return X.c<Y.c;

14         return X.d<Y.d;

15     }

16 } ip[1001];

17 

18 int main(void)

19 {

20     int T;cin>>T;

21     for(int kase=1;kase<=T;kase++)

22     {

23         int N,M;scanf("%d%d",&N,&M);

24         for(int i=1;i<=N;i++) scanf("%d.%d.%d.%d",&ip[i].a,&ip[i].b,&ip[i].c,&ip[i].d);

25         printf("Case #%d:\n",kase);

26         for(int i=1;i<=M;i++)

27         {

28             set <node> s;

29             node tem;

30             int A,B,C,D;scanf("%d.%d.%d.%d",&A,&B,&C,&D);

31             for(int j=1;j<=N;j++)

32             {

33                 tem.a=ip[j].a&A;

34                 tem.b=ip[j].b&B;

35                 tem.c=ip[j].c&C;

36                 tem.d=ip[j].d&D;

37                 s.insert(tem);

38             }

39             printf("%d\n",s.size());

40         }

41     }

42     return 0;

43 }
Aguin

 

2015百度之星资格赛 1004 放盘子
博弈。我觉得用我的脑子应该是想不到的。但是它把方法写在Hint里了。

由于图形对称。只要能放就是必胜。否则必败。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <cmath>

 4 using namespace std;

 5 const double pi=3.1415926;

 6 

 7 int main(void)

 8 {

 9     int T;cin>>T;

10     for(int kase=1;kase<=T;kase++)

11     {

12         int n;double a,r;

13         scanf("%d%lf%lf",&n,&a,&r);

14         if(r<=a/2/tan(pi/n)) printf("Case #%d:\nGive me a kiss!\n",kase);

15         else printf("Case #%d:\nI want to kiss you!\n",kase);

16     }

17     return 0;

18 }
Aguin

 

2015百度之星资格赛 1005 下棋

看讨论里有人找规律。可惜对这种东西一向不怎么敏感阿。

老老实实两边BFS。

分别两张地图上。针对每个格子。找出老头和马能走到该格子的最短时间。

倘若老头能在t走到某格子(x,y)。那么只要你喜欢。就能选择在任何t+k的时间让他走到这个格子。(k∈Z+&&t+k<=K)

同理。若马能在t走到(x,y)。就能在t+2*k走到这个格子。

最后扫一遍图。取马和老头时间相同中的最小值即可。

写的比较丑。已经丑出风格丑出水平了。真是屡教不改。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <cstring>

 4 # include <queue>

 5 using namespace std;

 6 # define CLR(x) memset(x,0,sizeof(x))

 7 # define mp make_pair

 8 int knight[1001][1001],king[1001][1001];

 9 int move[8][2]={{-2,1},{-1,2},{1,2},{2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}};

10 

11 int main(void)

12 {

13     int T;cin>>T;

14     for(int kase=1;kase<=T;kase++)

15     {

16         CLR(knight);CLR(king);

17         int N,M,K;scanf("%d%d%d",&N,&M,&K);

18         int Xking,Yking,Xknight,Yknight;

19         scanf("%d%d%d%d",&Xking,&Yking,&Xknight,&Yknight);

20         queue < pair<int,int> > q1,q2;

21         q1.push(mp(Xking,Yking));

22         q2.push(mp(Xknight,Yknight));

23         for(int i=1;i<=K;i++)

24         {

25             if(!q1.empty())

26             {

27                 int t=q1.size();

28                 while(t--)

29                 {

30                     int x=q1.front().first,y=q1.front().second;q1.pop();

31                     for(int j=-1;j<=1;j++)

32                         for(int k=-1;k<=1;k++)

33                             if((j||k)&&x+j>=1&&x+j<=N&&y+k>=1&&y+k<=M&&!king[x+j][y+k])

34                             {

35                                 king[x+j][y+k]=i;

36                                 q1.push(mp(x+j,y+k));

37                             }

38                 }

39             }

40             if(!q2.empty())

41             {

42                 int t=q2.size();

43                 while(t--)

44                 {

45                     int x=q2.front().first,y=q2.front().second;q2.pop();

46                     for(int j=0;j<8;j++)

47                         if(x+move[j][0]>=1&&x+move[j][0]<=N&&y+move[j][1]>=1&&y+move[j][1]<=M&&!knight[x+move[j][0]][y+move[j][1]])

48                         {

49                             knight[x+move[j][0]][y+move[j][1]]=i;

50                             q2.push(mp(x+move[j][0],y+move[j][1]));

51                         }

52                 }

53             }

54         }

55         int min=K+1;

56         for(int i=1;i<=N;i++)

57             for(int j=1;j<=M;j++)

58                 if(knight[i][j]&&king[i][j])

59                 {

60                     if(knight[i][j]>=king[i][j]&&knight[i][j]<min) min=knight[i][j];

61                     else

62                     {

63                         int tem=knight[i][j];

64                         for(;tem<=K;tem+=2)

65                             if(tem>=king[i][j]) break;

66                         if(tem<min) min=tem;

67                     }

68                 }

69         if(min>K) printf("Case #%d:\nOH,NO!\n",kase);

70         else printf("Case #%d:\n%d\n",kase,min);

71     }

72     return 0;

73 }
Aguin

 

2015百度之星资格赛 1006 单调区间

这个题目的关键信息在:百小度最近在逛博客,然后发现了一个有趣的问题。

懂了吗?没错!这是一个内涵题。

只要百度一下:一个n位数平均有多少个单调区间?

就能找到 http://www.matrix67.com/blog/archives/5296

QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ

然后……就没有然后了……

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 using namespace std;

 4 double num[100001],len[100001];

 5 

 6 int main(void)

 7 {

 8     for(int i=1;i<=100000;i++) {num[i]=1+1.0*(i-2)*19/27;len[i]=(46-1.0*38/i)/(19-1.0*11/i);}

 9     int T;cin>>T;

10     for(int kase=1;kase<=T;kase++)

11     {

12         int n;scanf("%d",&n);

13         printf("Case #%d:\n%.6lf %.6lf\n",kase,num[n],len[n]);

14     }

15     return 0;

16 }
Aguin

 

至此百度之星资格赛的题目就被Aguin、度娘以及鸡汁的出题人三人组成的小队不择手段的完成了。

 

5.25

 

hdu1754 I Hate It 线段树 点更新

题目没啥。但是手贱用了宏。于是T了还不知所以。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 using namespace std;

 4 # define maxn 200000+5

 5 int grade[maxn];

 6 

 7 int MAX(int x,int y){return x>=y ? x:y;}//不能用 # define MAX(x,y) x>y?x:y

 8 

 9 struct node

10 {

11     int a,b,max;

12 } tree[4*maxn];

13 

14 void maketree(int i,int a,int b)

15 {

16     tree[i].a=a;tree[i].b=b;

17     if(a<b)

18     {

19         maketree(2*i,a,(a+b)/2);

20         maketree(2*i+1,(a+b)/2+1,b);

21         tree[i].max=MAX(tree[2*i].max,tree[2*i+1].max);

22     }

23     else tree[i].max=grade[a];

24     return;

25 }

26 

27 void update(int i,int p,int grade)

28 {

29     if(tree[i].a==tree[i].b) {tree[i].max=grade;return;}

30     if(p<=(tree[i].a+tree[i].b)/2) update(2*i,p,grade);

31     else update(2*i+1,p,grade);

32     tree[i].max=MAX(tree[2*i].max,tree[2*i+1].max);

33     return;

34 }

35 

36 int query(int i,int A,int B)

37 {

38     if(tree[i].a>=A&&tree[i].b<=B) return tree[i].max;

39     int max=-1;

40     if(A<=(tree[i].a+tree[i].b)/2) max=MAX(max,query(2*i,A,B));

41     if(B>=(tree[i].a+tree[i].b)/2+1) max=MAX(max,query(2*i+1,A,B));

42     return max;

43 }

44 

45 int main(void)

46 {

47     int N,M;

48     while((scanf("%d%d",&N,&M))!=EOF)

49     {

50         for(int i=1;i<=N;i++) scanf("%d",grade+i);

51         maketree(1,1,N);

52         for(int i=1;i<=M;i++)

53         {

54             char s[5];int A,B;

55             scanf("%s%d%d",s,&A,&B);

56             if(s[0]=='Q') printf("%d\n",query(1,A,B));

57             if(s[0]=='U') update(1,A,B);

58         }

59     }

60     return 0;

61 }
Aguin

 

hdu1394 Minimum Inversion Number 线段树 点更新

数不大。可以暴解的。

然而一直理解不能线段树到底用在哪里了喂!

最后终于看懂了是区间计数然后每次询问(i,n-1)

感到智商十分捉鸡那。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <algorithm>

 4 using namespace std;

 5 # define maxn 5000+5

 6 int num[maxn];

 7 

 8 struct node

 9 {

10     int a,b,num;

11 }tree[maxn*4];

12 

13 void maketree(int i,int a,int b)

14 {

15     tree[i].a=a;tree[i].b=b;tree[i].num=0;

16     if(a==b) return;

17     maketree(2*i,a,(a+b)/2);

18     maketree(2*i+1,(a+b)/2+1,b);

19     return;

20 }

21 

22 int query(int i,int a,int b)

23 {

24     if(tree[i].a>=a&&tree[i].b<=b) return tree[i].num;

25     int sum=0;

26     if(a<=(tree[i].a+tree[i].b)/2) sum+=query(2*i,a,b);

27     if(b>=(tree[i].a+tree[i].b)/2+1) sum+=query(2*i+1,a,b);

28     return sum;

29 }

30 

31 void update(int i,int p)

32 {

33     if(tree[i].a==tree[i].b) {tree[i].num=1;return;}

34     if(p<=(tree[i].a+tree[i].b)/2) update(2*i,p);

35     else update(2*i+1,p);

36     tree[i].num=tree[2*i].num+tree[2*i+1].num;

37     return;

38 }

39 

40 int main(void)

41 {

42     int n;

43     while(cin>>n)

44     {

45         maketree(1,0,n-1);

46         int sum=0;

47         for(int i=0;i<n;i++)

48         {

49             scanf("%d",num+i);

50             sum+=query(1,num[i],n-1);

51             update(1,num[i]);

52         }

53         int MIN=sum;

54         for(int i=0;i<n;i++)

55             MIN=min(MIN,sum+=n-2*num[i]-1);

56         printf("%d\n",MIN);

57     }

58     return 0;

59 }
Aguin

 

hdu1698 Just a Hook 线段树 段更新

于是终于尝试了段更新。

事实上当时听课就没怎么听懂。

看了很多别人的代码。好像写法还蛮多的。

个人认为关键在于覆盖的时候杂色-1这个处理。

然而感觉这个方法并不是普遍适用的。

先消化这个入门级的吧。后续的再学习。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 using namespace std;

 4 # define maxn 100000+5

 5 

 6 struct node

 7 {

 8     int a,b,color;

 9 } tree[4*maxn];

10 

11 void maketree(int i,int a,int b)

12 {

13     tree[i].a=a;tree[i].b=b;tree[i].color=1;

14     if(a<b)

15     {

16         maketree(2*i,a,(a+b)/2);

17         maketree(2*i+1,(a+b)/2+1,b);

18     }

19     return;

20 }

21 

22 void update(int i,int a,int b,int color)

23 {

24     if(tree[i].color==color) return;

25     if(tree[i].a>=a&&tree[i].b<=b){tree[i].color=color;return;}

26     if(tree[i].color!=-1) {tree[2*i].color=tree[2*i+1].color=tree[i].color;tree[i].color=-1;}

27     if(a<=(tree[i].a+tree[i].b)/2) update(2*i,a,b,color);

28     if(b>=(tree[i].a+tree[i].b)/2+1) update(2*i+1,a,b,color);

29     return;

30 }

31 

32 int query(int i)

33 {

34     if(tree[i].color!=-1) return tree[i].color*(tree[i].b-tree[i].a+1);

35     return query(2*i)+query(2*i+1);

36 }

37 

38 int main(void)

39 {

40     int T;cin>>T;

41     for(int kase=1;kase<=T;kase++)

42     {

43         int N,Q;scanf("%d%d",&N,&Q);

44         maketree(1,1,N);

45         for(int i=1;i<=Q;i++)

46         {

47             int X,Y,Z;scanf("%d%d%d",&X,&Y,&Z);

48             update(1,X,Y,Z);

49         }

50         printf("Case %d: The total value of the hook is %d.\n",kase,query(1));

51     }

52     return 0;

53 }
Aguin

 

5.26

 

和高中的国象大神讨论了了百度的下棋。

他和我说了一个多小时。总结一下就是:可以贪。

我也觉得自己很sb。

首先对于老头而言。根本无需BFS。

因为老头的范围是以一个正方形扩大。每次边长增加2。

而骑士可以一直向着老头的初始位置走横日或者竖日趋近。

大神说当时比较忙。没空写。

然而现在已经不能提交了。等题放出有心情再写。

其实还是有细节需要注意的。

首先要注意骑士一步走进老头初始位置的情况。

其次注意边界。

放两个图。

第二周 5.24-5.30

第二周 5.24-5.30

 

poj3468 A Simple Problem with Integers 线段树 段更新 lazy-tag

终于学习了传说中号称线段树精髓的lazy-tag

关键还是那个tag与pushdown

感觉还不熟练呐。

(多次i与1写错。然而并不喜欢写宏)

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 using namespace std;

 4 typedef long long LL;

 5 # define maxn 100000+5

 6 int num[maxn];

 7 

 8 struct node

 9 {

10     int a,b;

11     LL sum,tag;

12 } tree[4*maxn];

13 

14 void pushdown(int i)

15 {

16     if(tree[i].tag)

17     {

18         tree[2*i].tag+=tree[i].tag;

19         tree[2*i+1].tag+=tree[i].tag;

20         tree[2*i].sum+=(tree[2*i].b-tree[2*i].a+1)*tree[i].tag;

21         tree[2*i+1].sum+=(tree[2*i+1].b-tree[2*i+1].a+1)*tree[i].tag;

22         tree[i].tag=0;

23     }

24     return;

25 }

26 

27 void maketree(int i,int a,int b)

28 {

29     tree[i].a=a;tree[i].b=b;tree[i].tag=0;

30     if(a<b)

31     {

32         maketree(2*i,a,(a+b)/2);

33         maketree(2*i+1,(a+b)/2+1,b);

34         tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;

35     }

36     else tree[i].sum=num[a];

37     return;

38 }

39 

40 void update(int i,int a,int b,int value)

41 {

42     if(tree[i].a>=a&&tree[i].b<=b) {tree[i].tag+=value; tree[i].sum+=(tree[i].b-tree[i].a+1)*value; return;}

43     pushdown(i);

44     if(a<=(tree[i].a+tree[i].b)/2) update(2*i,a,b,value);

45     if(b>=(tree[i].a+tree[i].b)/2+1) update(2*i+1,a,b,value);

46     tree[i].sum=tree[2*i].sum+tree[2*i+1].sum;

47     return;

48 }

49 

50 LL query(int i,int a,int b)

51 {

52     if(a<=tree[i].a&&b>=tree[i].b) return tree[i].sum;

53     pushdown(i);

54     LL sum=0;

55     if(a<=(tree[i].a+tree[i].b)/2) sum+=query(2*i,a,b);

56     if(b>=(tree[i].a+tree[i].b)/2+1) sum+=query(2*i+1,a,b);

57     return sum; 

58 }

59 

60 int main(void)

61 {

62     int N,Q;

63     while(cin>>N>>Q)

64     {

65         for(int i=1;i<=N;i++) scanf("%d",num+i);

66         maketree(1,1,N);

67         for(int i=1;i<=Q;i++)

68         {

69             char s[5];int a,b,c;

70             scanf("%s",s);

71             if(s[0]=='Q') {scanf("%d%d",&a,&b);printf("%lld\n",query(1,a,b));}

72             if(s[0]=='C') {scanf("%d%d%d",&a,&b,&c);update(1,a,b,c);}

73         }

74     }

75     return 0;

76 }
Aguin

 

5.27

 

大家都做了CF然而我又在睡觉。

然而反对暴力倡导和谐的我并没有补题。

 

今年寒假自己啃了C语法。学校里给我们专业开的是C++课。

前面半本书的课基本没听。都在写高代或者物理。但是也没有学C++后面的内容。

唯一会用的就是STL相关的一些基础。

后来开始讲后半本书了。不得不听课了。

讲了类和类模板才知道自己平常在用的STL是个啥。真是惭愧。

(然而感觉语法学的很糟糕)

 

晚上写一个线段树。STL依赖症于是T了一晚。明日再补吧。

 

5.28

 

poj2528 Mayor’s posters 线段树 离散化

这个线段树的部分和hdu1698的涂色是一样的。

但是加上了一个叫离散化的东西。

在上周BC的时候用map+queue做了一个离散化的题目(当时并不知道叫离散化)

于是一开始就像用set+map做。

但是自己测样例的时候大概过了1s才跳出答案- -

于是去掉了set的部分。用了一个大大的数组。但是T了。

感觉应该是不能用map了。

看了几个别人写的离散化。不知道干嘛觉得很不顺眼。(大概和别人看我不爽是一样的)

后来就自己乱写了。

结果内存用了好多。跑得也不快。但是总算是过了。

第二周 5.24-5.30
# include <iostream>

# include <cstdio>

# include <cstring>

using namespace std;

int ans,ord[2][10005],mark[10005],point[10000005];



struct node

{

    int a,b,cover;

} tree[4*20005];



void maketree(int i,int a,int b)

{

    tree[i].a=a;tree[i].b=b;tree[i].cover=0;

    if(a<b)

    {

        maketree(2*i,a,(a+b)/2);

        maketree(2*i+1,(a+b)/2+1,b);

    }

    return;

}



void update(int i,int a,int b,int cover)

{

    if(a<=tree[i].a&&b>=tree[i].b) {tree[i].cover=cover;return;}

    if(tree[i].cover!=-1) {tree[2*i].cover=tree[2*i+1].cover=tree[i].cover; tree[i].cover=-1;}

    if(a<=(tree[i].a+tree[i].b)/2) update(2*i,a,b,cover);

    if(b>=(tree[i].a+tree[i].b)/2+1) update(2*i+1,a,b,cover);

    return;

}



void query(int i)

{

    if(!tree[i].cover) return;

    if(tree[i].cover!=-1) {if(!mark[tree[i].cover]) ans++; mark[tree[i].cover]=1; return;}

    query(2*i);query(2*i+1);

    return;

}



int main(void)

{

    int c;cin>>c;

    while(c--)

    {

        int n,cnt=0; scanf("%d",&n);

        memset(mark,0,sizeof(mark));

        memset(point,0,sizeof(point));

        for(int i=1;i<=n;i++)

        {

            scanf("%d%d",ord[0]+i,ord[1]+i);

            point[ord[0][i]]=point[ord[1][i]]=1;

        }

        for(int i=1;i<=10000000;i++) if(point[i]) point[i]=++cnt;

        maketree(1,1,cnt);

        for(int i=1;i<=n;i++) update(1,point[ord[0][i]],point[ord[1][i]],i);

        ans=0; query(1);

        printf("%d\n",ans);

    }

    return 0;

}
Aguin

 

5.29

 

郏老大讲树状数组。算法课签到+1。

感觉就是学习了一种虽然不知道怎么回事但是很好用的求和工具。

课上讲的题好像都见过。于是用树状数组重新写一次。

 

hdu1166 敌兵布阵 点更新 求和 树状数组

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <cstring>

 4 using namespace std;

 5 int N,c[50005]={0};

 6 

 7 int lowbit(int s)

 8 {return s&(-s);}

 9 

10 void add(int i,int x)

11 {

12     while(i<=N){c[i]+=x; i+=lowbit(i);}

13     return;

14 }

15 

16 int sum(int i)

17 {

18     int ans=0;

19     while(i>0) {ans+=c[i];i-=lowbit(i);}

20     return ans;

21 }

22 

23 int main(void)

24 {

25     int T;cin>>T;

26     for(int kase=1;kase<=T;kase++)

27     {

28         memset(c,0,sizeof(c));

29         scanf("%d",&N);

30         for(int i=1;i<=N;i++)

31         {

32             int x;scanf("%d",&x);

33             add(i,x);

34         }

35         printf("Case %d:\n",kase);

36         while(1)

37         {

38             char s[10];int a,b;

39             scanf("%s",s);

40             if(s[0]=='E') break;

41             scanf("%d%d",&a,&b);

42             if(s[0]=='A') add(a,b);

43             if(s[0]=='S') add(a,-b);

44             if(s[0]=='Q') printf("%d\n",sum(b)-sum(a-1));

45         }

46     }

47     return 0;

48 }
Aguin

 

hdu1394 Minimum Inversion Number 求逆序数 树状数组

题目里面是0~n-1的。好像就不好用了(可能是我不会)。于是变成1~n+1。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <cstring>

 4 # include <algorithm>

 5 using namespace std;

 6 int n,c[5005],num[5005];

 7 

 8 int lowbit(int s)

 9 {return s&(-s);}

10 

11 void add(int i,int x)

12 {

13     while(i<=n+1){c[i]+=x; i+=lowbit(i);}

14     return;

15 }

16 

17 int sum(int i)

18 {

19     int ans=0;

20     while(i>0) {ans+=c[i];i-=lowbit(i);}

21     return ans;

22 }

23 

24 int main(void)

25 {

26     while(cin>>n)

27     {

28         memset(c,0,sizeof(c));

29         int tem=0;

30         for(int i=0;i<n;i++)

31         {

32             scanf("%d",num+i);

33             tem+=sum(n+1)-sum(num[i]+1);

34             add(num[i]+1,1);

35         }

36         int ans=tem;

37         for(int i=0;i<n;i++) ans=min(ans,tem+=n-2*num[i]-1);

38         printf("%d\n",ans); 

39     }

40     return 0;

41 }
Aguin

 

5.30

 

继续补树状数组。

其实当讲到 段更新 点询问 的时候。

首先想到的是西电oj开服赛的那个挖掘机

虽然说这里的询问很简单。不用树状数组或者线段树。

但是求和的时候用到了相同的思想。

树状数组只是工具。关键是如果把问题转化为求和。

 

郏老大在自家oj挂题了。

清点人数

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <cstring>

 4 using namespace std;

 5 int n,c[500005];

 6 

 7 int lowbit(int s)

 8 {return s&(-s);}

 9 

10 void add(int i,int x)

11 {

12     while(i<=n){c[i]+=x; i+=lowbit(i);}

13     return;

14 }

15 

16 int sum(int i)

17 {

18     int ans=0;

19     while(i>0) {ans+=c[i];i-=lowbit(i);}

20     return ans;

21 }

22 

23 int main(void)

24 {

25     int k;

26     while(cin>>n>>k)

27     {

28         memset(c,0,sizeof(c));

29         for(int i=0;i<k;i++)

30         {

31             char s[5];int a,b;

32             scanf("%s",s);

33             if(s[0]=='A') {scanf("%d",&a); printf("%d\n",sum(a));}

34             if(s[0]=='B') {scanf("%d%d",&a,&b); add(a,b);}

35             if(s[0]=='C') {scanf("%d%d",&a,&b); add(a,-b);}

36         }

37     }

38     return 0;

39 }
Aguin

 

弱弱的战壕

先排序。再统计比它小的。和求顺序对很像。

第二周 5.24-5.30
 1 # include <iostream>

 2 # include <cstdio>

 3 # include <cstring>

 4 # include <algorithm>

 5 using namespace std;

 6 int c[32005],ans[15005];

 7 

 8 struct cor

 9 {

10     int x,y;

11 } point[15005];

12 

13 bool cmp(cor a,cor b)

14 {

15     return a.x==b.x? a.y<b.y:a.x<b.x ;

16 }

17 

18 int lowbit(int s)

19 {return s&(-s);}

20 

21 void add(int i,int x)

22 {

23     while(i<=32000){c[i]+=x; i+=lowbit(i);}

24     return;

25 }

26 

27 int sum(int i)

28 {

29     int ans=0;

30     while(i>0) {ans+=c[i];i-=lowbit(i);}

31     return ans;

32 }

33 

34 int main(void)

35 {

36     int n;

37     while(cin>>n)

38     {

39         memset(c,0,sizeof(c));

40         memset(ans,0,sizeof(ans));

41         for(int i=0;i<n;i++) scanf("%d%d",&point[i].x,&point[i].y);

42         sort(point,point+n,cmp);

43         for(int i=0;i<n;i++) {ans[sum(point[i].y)]++; add(point[i].y,1);}

44         for(int i=0;i<n;i++) printf("%d\n",ans[i]);

45     }

46     return 0;

47 }
Aguin

 

下午百度爆0了。

感觉心很累。好像不会再码了。

1001想贪。贪错了。

后来拓神教我。然而没怎么看懂。又去问铖霸。

铖霸叫我好好看题。才发现看错题。

1005置换。不知道哪里写错了。

sample3过不了。我拧过了。的确是105次- -

计算几何什么的不会。其他的根本不知道是啥。

 

事情越来越多了。接下来的两周会更忙。

暑假快来吧。

 

23+1=24;

你可能感兴趣的:(第二周 5.24-5.30)