zoukankan      html  css  js  c++  java
  • 20190807

    咕了很长时间了QAQ

    T1. 旋转子段

     话说 n^2 思路也很棒....(对于想不到正解的我而言

     枚举中心点 mid ,长度 len,由小长度向大长度双向扩展. 其实离正解差一个结论,就是你的 旋转边界 旋转过后 一定能对答案做 1 个贡献.(要不你完全可以将区间左右同时缩小 即由 [ i , j ] 变为 [ i + 1 , j - 1 ] .)所有优秀区间一定满足上述条件. 所以可以根据 mid 分类,对于每一个 mid 执行上述扩展操作,并更新答案. 复杂度的话,由于只有 n 个上述符合条件的边界,加上 sort 共是 nlogn.

     

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #define QAQ 500010
     9 #define re register
    10 #define fup(i,a,b) for(re int i=a;i<=b;++i)
    11 #define fdn(i,a,b) for(re int i=a;i>=b;--i)
    12 #define mp(a,b) make_pair(a,b)
    13 int n;
    14 int sum[QAQ];
    15 using namespace std;
    16 std::vector< pair<int,int> >wtf[QAQ<<1];
    17 inline int read() {
    18     re int x(0),f(1);re char ch=getchar();
    19     while(ch<'0'||ch>'9')   { if(ch=='-') f=-1; ch=getchar(); }
    20     while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    21     return x*f;
    22 }
    23 int main() { n=read();
    24     fup(i,1,n) {
    25         re int l=read(),r=i;
    26         sum[i]=sum[i-1]+(l==r);
    27         if(l>r) swap(l,r);
    28         wtf[l+r].push_back(mp(r,l));
    29     }
    30     if(sum[n]==n) std::cout<<sum[n]<<std::endl,exit(0);
    31     re int ans=0;
    32     fup(i,1,n<<1) if(wtf[i].size()!=0) {
    33         std::sort(wtf[i].begin(),wtf[i].end());
    34         fup(j,0,wtf[i].size()-1) {
    35             re int l=wtf[i][j].second;
    36             re int r=wtf[i][j].first;
    37             ans=std::max(ans,sum[n]-sum[r]+sum[l-1]+j+1);
    38         }
    39     }
    40     std::cout<<ans<<std::endl;
    41 }
    View Code

    T2. 走格子

     考试时根本没打,真没想到这么水...

     建图跑spfa就ojbk..

     考虑如何建图.

     首先相邻边可连,然后就是传送门的使用.

     可以发现最佳食用方法是由离自己当前位置最近的墙biu~然后穿过去,所以需要 bfs (或其他)处理离自己最近的墙,建当前位置经墙到别的位置的边.(话说这种题还真好玩虽然不善良

     

     1 #include <queue>
     2 #include <cstdio>
     3 #include <vector>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <algorithm>
     7 #define QAQ 502
     8 #define re register
     9 #define fup(i,a,b) for(re int i=a;i<=b;++i)
    10 #define fdn(i,a,b) for(re int i=a;i>=b;--i)
    11 using namespace std;
    12 int n,m,st,ed;
    13 int     v[QAQ*QAQ];
    14 int  diss[QAQ*QAQ];
    15 char map[QAQ][QAQ];
    16 int  dis[QAQ][QAQ];
    17 int upto[QAQ][QAQ];
    18 int lfto[QAQ][QAQ];
    19 int rgto[QAQ][QAQ];
    20 int dnto[QAQ][QAQ];
    21 vector< pair<int, int> >wtf[QAQ*QAQ];
    22 inline int read() {
    23     re int x(0),f(1);re char ch=getchar();
    24     while(ch<'0'||ch>'9')   { if(ch=='-') f=-1; ch=getchar(); }
    25     while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    26     return x*f;
    27 }
    28 queue< pair<int, int> >qwq;
    29 inline int Get_id(int x,int y) {
    30     return (x-1)*m+y;
    31 }
    32 inline void Try_push(int x,int y,int ds) {
    33     if(map[x][y]=='.'&&!dis[x][y])
    34     dis[x][y]=ds,qwq.push(make_pair(x,y));
    35 }
    36 int main() {
    37     n=read(),m=read();
    38     fup(i,1,n) scanf("%s",map[i]+1);
    39     fup(i,1,n) fup(j,1,m) {
    40         if(map[i][j]=='#') qwq.push(make_pair(i,j));
    41         if(map[i][j]=='C') map[i][j]='.',st=Get_id(i,j);
    42         else if(map[i][j]=='F') map[i][j]='.',ed=Get_id(i,j);
    43     }
    44     //while(!qwq.size())嘤???
    45     while(qwq.size()) {
    46         re int x=qwq.front().first;
    47         re int y=qwq.front().second;
    48         qwq.pop();
    49         Try_push(x+1,y,dis[x][y]+1);
    50         Try_push(x-1,y,dis[x][y]+1);
    51         Try_push(x,y+1,dis[x][y]+1);
    52         Try_push(x,y-1,dis[x][y]+1);
    53     }
    54     fup(i,1,n) fup(j,1,m) if(map[i][j]=='.') {
    55         if (map[i-1][j]=='#') upto[i][j]=Get_id(i,j);
    56         else upto[i][j]=upto[i-1][j];
    57         if (map[i][j-1]=='#') lfto[i][j]=Get_id(i,j);
    58         else lfto[i][j]=lfto[i][j-1];
    59     }
    60     fdn(i,n,1) fdn(j,m,1) if(map[i][j]=='.') {
    61         if (map[i+1][j]=='#') dnto[i][j]=Get_id(i,j);
    62         else dnto[i][j]=dnto[i+1][j];
    63         if (map[i][j+1]=='#') rgto[i][j]=Get_id(i,j);
    64         else rgto[i][j]=rgto[i][j+1];
    65     }
    66     fup(i,1,n) fup(j,1,m) if(map[i][j]=='.') {
    67         if (map[i][j+1]=='.') wtf[Get_id(i,j)].push_back(make_pair(Get_id(i,j+1),1)),
    68                               wtf[Get_id(i,j+1)].push_back(make_pair(Get_id(i,j),1));
    69         if (map[i+1][j]=='.') wtf[Get_id(i,j)].push_back(make_pair(Get_id(i+1,j),1)),
    70                                    wtf[Get_id(i+1,j)].push_back(make_pair(Get_id(i,j),1));
    71         if (upto[i][j]!=Get_id(i,j)) wtf[Get_id(i,j)].push_back(make_pair(upto[i][j],dis[i][j]));
    72         if (dnto[i][j]!=Get_id(i,j)) wtf[Get_id(i,j)].push_back(make_pair(dnto[i][j],dis[i][j]));
    73         if (lfto[i][j]!=Get_id(i,j)) wtf[Get_id(i,j)].push_back(make_pair(lfto[i][j],dis[i][j]));
    74         if (rgto[i][j]!=Get_id(i,j)) wtf[Get_id(i,j)].push_back(make_pair(rgto[i][j],dis[i][j]));
    75     }
    76     memset(diss,0x3f,sizeof diss);
    77     memset(v,0,sizeof v);diss[st]=0;
    78     queue<int>qaq;
    79     qaq.push(st),v[st]=1;
    80     while(qaq.size()) {
    81         re int x=qaq.front();
    82         qaq.pop();v[x]=0;
    83         if (wtf[x].size())
    84         fup(i,0,wtf[x].size()-1) {
    85             re int y=wtf[x][i].first;
    86             re int d=wtf[x][i].second;
    87             if (diss[y]>diss[x]+d) {
    88                 diss[y]=diss[x]+d;
    89                 if (v[y])continue;
    90                 qaq.push(y),v[y]=1;
    91             }
    92         }
    93     }
    94     printf("%d
    ",diss[ed]);
    95 }
    View Code

    T3. 柱状图

    我才不会说我和上次T1一样推了半年的柿子QAQ(最后5分钟打了个过不了样例的暴力骗到了15分 

     然而正解和数学柿子没卵关系嘤

     首先这是一个单谷函数

    设 f(x) 代表最高柱子高度为 x 时的调整所需花费。显然,当 x 取到一个恰当的值的时候,可以使得花费最小,当然,这样的值可能有很多个。但是不难发现只要任何一个其他的x'不能取得更优的值,就可以保证这是一个单谷函数(由于相邻的柱子高度差只能为1)(w又颓的网上证明

     所以可以三分.

     所以枚举最高点,三分高度并判定 就可以 n^2logn 得到 60 分的好成绩.....

     考虑如何优化 三分求解时利用两个树状数组来维护最高点两边的关键值,然后利用树状数组的求前缀和功能计算花费即可

     $left [ cnt_l*(h_x-x)-sum_{i=1}^{pos}(h_i-i) ight ] + left [ sum_{i=pos+1}^{n}(h_i-i)-cnt_r*(h_x-x) ight ]$

     以上为左侧

     $left [ cnt_l*(h_x+x)-sum_{i=1}^{pos}(h_i+i) ight ] + left [ sum_{i=pos+1}^{n}(h_i+i)-cnt_r*(h_x+x) ight ]$

     以上为右侧

     cntl 为关键值小于 h[x]-x ( h[x]+x ) 并且下标也小于 x 的数量  cntr关键值大于 h[x]-x ( h[x]+x ) 并且下标也小于 x 的数量

     

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #define QAQ 100005
     6 #define re register
     7 #define int long long
     8 #define lowbit(x) x&-x
     9 #define pait pair<int,int>
    10 #define mp(a,b) make_pair(a,b)
    11 #define fup(i,a,b) for(re int i=a;i<=b;++i)
    12 #define fdn(i,a,b) for(re int i=a;i>=b;--i)
    13 using namespace std;
    14 int n,ans,a[QAQ],rkl[QAQ],rkr[QAQ];
    15 inline int read() {
    16     re int x(0),f(1);re char ch=getchar();
    17     while(ch<'0'||ch>'9')   { if(ch=='-') f=-1; ch=getchar(); }
    18     while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    19     return x*f;
    20 }
    21 struct node {
    22     int val,id;
    23     friend bool operator < (node a,node b) {
    24         return a.val < b.val;
    25     }
    26 }l[QAQ],r[QAQ];
    27 pait operator + (pait a,pait b) {
    28     return mp(a.first+b.first,a.second+b.second);
    29 }
    30 pait operator - (pait a,pait b) {
    31     return mp(a.first-b.first,a.second-b.second);
    32 }
    33 struct tree {
    34     int sum[QAQ],cnt[QAQ];
    35     inline void insert(re int x,pait now) {
    36         for(;x<=n;x+=lowbit(x))
    37             sum[x]+=now.first,
    38             cnt[x]+=now.second;
    39     }
    40     inline pait query_val(re int x) {
    41         pait ans=mp(0,0);
    42         for(;x;x-=lowbit(x)) 
    43             ans=ans+mp(sum[x],cnt[x]);
    44         return ans;
    45     }
    46     inline pait query_line(re int l,re int r) {
    47         if(l>r) return mp(0,0);
    48         return query_val(r)-query_val(l-1);
    49     }
    50 }Right,Left;
    51 int find(node *what,re int dat) {
    52     re int l=1,r=n,mid;
    53     while(mid=l+r>>1,l+1<r) {
    54         if(what[mid].val>dat) r=mid;
    55         else l=mid;
    56     }
    57     if(what[r].val<=dat) return r;
    58     if(what[l].val<=dat) return l;
    59     return 0;
    60 }
    61 int calc(re int id,re int high) {
    62     re int res=abs(high-a[id]);re pait cost;
    63     re int pos=find(l,high-id);
    64     cost=Left.query_val(pos);
    65     res+=(high-id)*cost.second-cost.first;
    66     cost=Left.query_line(pos+1,n);
    67     res+=cost.first-(high-id)*cost.second;
    68     pos=find(r,high+id);
    69     cost=Right.query_val(pos);
    70     res+=(high+id)*cost.second-cost.first;
    71     cost=Right.query_line(pos+1,n);
    72     res+=cost.first-(high+id)*cost.second;
    73     return res;
    74 }
    75 main() {
    76     n=read();re int maxx=0,ans=0x7f7f7f7f7f7f7f7f;
    77     fup(i,1,n) a[i]=read(),maxx=max(maxx,a[i]);
    78     fup(i,1,n)
    79         l[i]=(node){ a[i] - i, i },
    80         r[i]=(node){ a[i] + i, i };
    81     sort(l+1,l+n+1),sort(r+1,r+n+1);
    82     fup(i,1,n)
    83         rkl[l[i].id] = i,
    84         rkr[r[i].id] = i;
    85     fup(i,1,n) Right.insert(rkr[i],mp(r[rkr[i]].val,1));
    86     fup(i,1,n) {
    87         Right.insert(rkr[i],mp(-r[rkr[i]].val,-1));
    88         re int ll=max(i,n-i+1),rr=maxx+n;
    89         while(ll+1<rr){
    90             re int mid=(ll+rr)>>1;
    91             if(calc(i,mid-1)>=calc(i,mid))  ll=mid;
    92             else  rr=mid;
    93         }
    94         ans=min(ans,calc(i,ll));  ans=min(ans,calc(i,rr));
    95         Left.insert(rkl[i],mp(l[rkl[i]].val,1));
    96     } std::cout<<ans<<std::endl;
    97 }
    View Code

    (话说为什么不打模拟退火呢?

  • 相关阅读:
    【Foreign】无聊的计算姬 [Lucas][BSGS]
    【Foreign】远行 [LCT]
    Leetcode题解(十)
    Leetcode题解(九)
    Leetcode题解(八)
    Leetcode题解(七)
    Leetcode题解(六)
    Leetcode题解(五)
    Leetcode题解(四)
    Leetcode题解(三)
  • 原文地址:https://www.cnblogs.com/bilibiliSmily/p/11323332.html
Copyright © 2011-2022 走看看