atcoder beginner 346 C F G 题解

 

 

看到别人的视频讲解 AtCoder Beginner Contest 346 A 至 G 題讲解 by dreamoon

 

C

如果用sort写,那么再从小到大遍历也需要写几行

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdbool>
#include <string>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <ctime>
#include <stack>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define ll long long
#define ull unsigned long long

const ll mod_1=1e9+7;
const ll mod_2=998244353;

const double eps_1=1e-5;
const double eps_2=1e-10;

const int maxn=2e5+10;

int a[maxn];




int main()
{
    int n,i,k;
    ll sum=0;
    scanf("%d%d",&n,&k);
    for (i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    sort(a+1,a+n+1);
    sum=1ll*k*(k+1)/2;
    a[0]=0;
    for (i=1;i<=n;i++)
        if (a[i]<=k && a[i]!=a[i-1])
            sum-=a[i];
    printf("%lld",sum);
    return 0;
}

 

map也是同样的情况,是否出现过,map_1.find()!=map_1.end()

 

set的写法

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <cstdbool>
 6 #include <string>
 7 #include <algorithm>
 8 #include <iostream>
 9 #include <sstream>
10 #include <ctime>
11 #include <stack>
12 #include <vector>
13 #include <queue>
14 #include <set>
15 #include <map>
16 using namespace std;
17 #define ll long long
18 #define ull unsigned long long
19 
20 const ll mod_1=1e9+7;
21 const ll mod_2=998244353;
22 
23 const double eps_1=1e-5;
24 const double eps_2=1e-10;
25 
26 const int maxn=2e5+10;
27 
28 set<int> set_1;
29 
30 int main()
31 {
32     int n,k,i,a;
33     ll sum;
34     scanf("%d%d",&n,&k);
35     sum=k*(k+1ll)/2;
36     for (i=1;i<=n;i++)
37     {
38         scanf("%d",&a);
39         if (a<=k)
40             sum -= set_1.insert(a).second * a;
41     }
42     printf("%lld",sum);
43 
44 
45     return 0;
46 }

 

F

一个比较明显的,从这个字符a开始,后面k个字符b后的的位置(dp) + 二分。

预估场上的时间,还是有些细节容易写错,当最后剩余时间不多的时候容易慌。

这样 1 前面A-E尽快做完,这样F容易安全渡过  2 F在剩余时间少的时候,大心脏的完成。都要培养

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <cstdbool>
  6 #include <string>
  7 #include <algorithm>
  8 #include <iostream>
  9 #include <sstream>
 10 #include <ctime>
 11 #include <stack>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 using namespace std;
 17 #define ll long long
 18 #define ull unsigned long long
 19 
 20 const ll mod_1=1e9+7;
 21 const ll mod_2=998244353;
 22 
 23 const double eps_1=1e-5;
 24 const double eps_2=1e-10;
 25 
 26 const int maxn=1e5+10;
 27 
 28 
 29 
 30 char str1[maxn], str2[maxn];
 31 ll f[26][maxn], cnt[26], next_fit_pos[26][maxn], next_fit_index[26][maxn];
 32 ll s2[maxn];
 33 
 34 int main()
 35 {
 36     ll n,len1,len2,ch,i,j,k,o,pos_in_loop,cur_pos_index,xx,yy,max_length;
 37     ll l,r,mid,cur_pos;
 38     bool vis;
 39     cin>>n;
 40     scanf("%s%s",str1,str2);
 41     len1=strlen(str1);
 42     len2=strlen(str2);
 43     max_length=len1*n;
 44     memset(cnt,0,sizeof(cnt));
 45     //先加上试试
 46     memset(next_fit_pos,0,sizeof(next_fit_pos));
 47     memset(next_fit_index,0,sizeof(next_fit_index));
 48     memset(f,0,sizeof(f));
 49     memset(s2,0,sizeof(s2));
 50 
 51     for (i=0;i<len1;i++)
 52     {
 53         ch = str1[i]-'a';
 54         f[ch][ cnt[ch]++ ]=i;
 55     }
 56 
 57     for (i=0;i<len2;i++)
 58         s2[i] = str2[i]-'a';
 59 
 60     for (i=0;i<26;i++)
 61         if (cnt[i]>0)
 62         {
 63             k=0;
 64             for (j=0;j<len1;j++)
 65             {
 66                 if (j==f[i][k])
 67                 {
 68                     k++;
 69                     if (cnt[i]==k)
 70                     {
 71                         for (o=j;o<len1;o++)
 72                         {
 73                             next_fit_pos[i][o]=len1+f[i][0]-o;
 74                             next_fit_index[i][o]=0;
 75                         }
 76                         break;
 77                     }
 78                 }
 79                 next_fit_pos[i][j]=f[i][k]-j;
 80                 next_fit_index[i][j]=k;
 81             }
 82         }
 83 
 84     //binary search
 85 
 86     l=1,r=n*len1/len2;
 87 
 88     while (l<=r)
 89     {
 90         mid = (l+r)/2;
 91 
 92         //if ok
 93 
 94         vis=1;
 95 
 96         cur_pos=-1;
 97         for (i=0;i<len2;i++)
 98         {
 99             ch=s2[i];
100 
101             if (cnt[ch]==0)
102             {
103                 cout<<0;
104                 return 0;
105             }
106 
107             if (cur_pos==-1)
108             {
109                 cur_pos=f[ch][0];
110                 cur_pos_index=0;
111             }
112             else
113             {
114                 pos_in_loop=cur_pos%len1;
115                 cur_pos += next_fit_pos[ch][pos_in_loop];
116                 cur_pos_index = next_fit_index[ch][pos_in_loop];
117             }
118 
119             xx=(mid-1)/cnt[ch];
120             yy=(mid-1)%cnt[ch];
121 
122             yy+=cur_pos_index;
123             if (yy>=cnt[ch])
124             {
125                 xx++;
126                 yy-=cnt[ch];
127             }
128 
129             cur_pos = cur_pos - f[ch][cur_pos_index] + xx * len1 + f[ch][yy];
130 
131             if (cur_pos>=max_length)
132             {
133                 vis=0;
134                 break;
135             }
136         }
137 
138         if (!vis)
139             r=mid-1;
140         else
141             l=mid+1;
142     }
143 
144     cout<<r;
145 
146     return 0;
147 }
148 /*
149 3
150 aaa
151 aaa
152 
153 3
154 aaa
155 a
156 
157 3
158 aaaaa
159 aaaa
160 
161 
162 =============
163 
164 asd容易乱打
165 
166 3
167 sadasdasdsdasdaasdas
168 asd
169 
170 output 7
171 sadasdasdsdasdaasdassadasdasdsdasdaasdassadasdasdsdasdaasdas
172 
173 =============
174 
175 
176 
177 
178 
179 
180 */

 

 

 

G

题目转化为求二维线段树

二维线段树 - congmingyige - 博客园 (cnblogs.com)  : 这种写法内存不太够用,a[maxn*4][maxn*4]

 

题目 CSES - Area of Rectangles ; 对应程序 CSES-Solutions/Additional Problems/Area of Rectangles.cpp at main · Jonathan-Uy/CSES-Solutions · GitHub

 

扫描线

扫描线 - OI Wiki (oi-wiki.org) 例题也是二维矩阵相交面积

 

线段树 - OI Wiki (oi-wiki.org)

 

如果要求修改区间[l,r] ,把所有包含在区间[l,r] 中的节点都遍历一次、修改一次,时间复杂度无法承受。我们这里要引入一个叫做 「懒惰标记」 的东西。

懒惰标记,简单来说,就是通过延迟对节点信息的更改,从而减少可能不必要的操作次数。每次执行修改时,我们通过打标记的方法表明该节点对应的区间在某一次操作中被更改,但不更新该节点的子节点的信息。实质性的修改则在下一次访问带有标记的节点时才进行。

 

 

===

没有求a[l]-a[r],所以不用lazy标记

加上文件头 #include <array>

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <cstdbool>
  6 #include <string>
  7 #include <algorithm>
  8 #include <iostream>
  9 #include <sstream>
 10 #include <ctime>
 11 #include <stack>
 12 #include <vector>
 13 #include <queue>
 14 #include <set>
 15 #include <map>
 16 #include <array>
 17 using namespace std;
 18 #define LL long long
 19 #define ULL unsigned long long
 20 
 21 const LL mod_1=1e9+7;
 22 const LL mod_2=998244353;
 23 
 24 const double eps_1=1e-5;
 25 const double eps_2=1e-10;
 26 
 27 const int maxn=2e5+10;
 28 const int maxm=maxn*4;
 29 
 30 array<int,4> op[maxn*2];
 31 
 32 int a[maxn],nex[maxn],lef[maxn],righ[maxn];
 33 
 34 int leftmost_pos[maxn],rightmost_pos[maxn];
 35 
 36 int f[maxm],tag[maxm],siz[maxm];
 37 
 38 LL result=0;
 39 
 40 void build(int index, int l, int r)
 41 {
 42     siz[index]=r-l+1;
 43     if (l==r)
 44         return;
 45     int m=(l+r)>>1;
 46     build(index<<1,l,m);
 47     build(index<<1|1,m+1,r);
 48 }
 49 
 50 void modify(int index,int l, int r, int ll, int rr, int val)
 51 {
 52     if (ll<=l && r<=rr)
 53     {
 54         tag[index]+=val;
 55 
 56         if (l==r)
 57             f[index]= (tag[index]>0 ? 1:0);
 58         else
 59             f[index]= (tag[index]>0 ? siz[index]:f[index<<1]+f[index<<1|1]);
 60         return;
 61     }
 62     int m=(l+r)>>1;
 63     if (m>=ll)
 64         modify(index<<1,l,m,ll,rr,val);
 65     if (m+1<=rr)
 66         modify(index<<1|1,m+1,r,ll,rr,val);
 67     f[index]= (tag[index]>0 ? siz[index]:f[index<<1]+f[index<<1|1]);
 68 }
 69 
 70 int main()
 71 {
 72     int n,i,y_last=-1;
 73     scanf("%d",&n);
 74     for (i=1;i<=n;i++)
 75         scanf("%d",&a[i]);
 76     for (i=1;i<=n;i++)
 77     {
 78         leftmost_pos[i]=1;
 79         rightmost_pos[i]=n;
 80     }
 81     for (i=1;i<=n;i++)
 82     {
 83         lef[i] = leftmost_pos[ a[i] ];
 84         leftmost_pos[ a[i] ] = i+1;
 85     }
 86     for (i=n;i>=1;i--)
 87     {
 88         righ[i] = rightmost_pos[ a[i] ];
 89         rightmost_pos[ a[i] ] = i-1;
 90     }
 91 
 92     for (i=1;i<=n;i++)
 93     {
 94         op[(i-1)<<1] = {i, 1, lef[i]+1, i+1};   ///这两个+1性质不同
 95         op[(i-1)<<1|1] = {righ[i]+1, -1, lef[i]+1, i+1};
 96     }
 97 
 98     sort(op, op+n*2);
 99     memset(f,0,sizeof(f));
100     memset(tag,0,sizeof(tag));
101 
102     int value_max=n+1;
103     build(1,1,value_max);
104 
105     for (i=0;i<n*2;i++)
106     {
107         result+=(op[i][0]-y_last)*f[1];
108         modify(1, 1, value_max, op[i][2], op[i][3], op[i][1]);
109         y_last=op[i][0];
110     }
111     cout<<result;
112 
113     return 0;
114 }
115 /*
116 1
117 1
118 
119 2
120 1 2
121 
122 3
123 1 2 3
124 
125 4
126 1 2 3 4
127 */

 

posted @ 2024-03-29 19:30  congmingyige  阅读(16)  评论(0编辑  收藏  举报