3.26 - 4.14
3.26-4.14
CF-629D
[l,r]
은 id=l에서 id=j의 최대 dp값#include
using namespace std;
const int N = 100000;
double vol[N],r,h;
int n,has[N],g[N],dp[N],tot;
int c[N];
vector v;
int getId(double a){
return lower_bound(v.begin(),v.end(),a)-v.begin()+1;
}
struct Tree{
int l,r;
double data;
}t[4*N];
void build(int p,int l,int r){
t[p].l = l;
t[p].r = r;
if(l==r){
t[p].data = 0;return;
}
int mid = l+r>>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].data = 0;
}
void change(int p,int x,double val){
if(t[p].l == t[p].r && t[p].l == x){
t[p].data = max(t[p].data,val);
return ;
}
int mid = (t[p].l+t[p].r)>>1;
if(x<=mid)change(p*2,x,val);
else change(p*2+1,x,val);
t[p].data = max(t[p*2].data,t[p*2+1].data);
}
double ask(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r)return t[p].data;
int mid = (t[p].l+t[p].r)>>1;
double val = 0;
if(l<=mid)val = max(val,ask(p*2,l,r));
if(r>mid)val = max(val,ask(p*2+1,l,r));
return val;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
scanf("%lf%lf",&r,&h);
vol[i] = acos(-1) * r * r * h;
v.push_back(vol[i]);
}
sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
build(1,1,n);
double res = 0;
for(int i=1;i<=n;i++){
int id = getId(vol[i]);
double now = ask(1,1,id-1);
now = max(vol[i],vol[i]+now);
res = max(res,now);
change(1,id,now);
}
printf("%.10lf
",res);
return 0;
}
#include
using namespace std;
const int N = 100010;
const int inf = 0x3f3f3f3f;
double vol[N],c[N];
vector v;
int n,g[N];
int getId(double res){
return lower_bound(v.begin(),v.end(),res) - v.begin() + 1;
}
void add(int x,double y){
c[x] = y;
for(;x<=n;x+=x&-x)c[x] = max(c[x],y);
}
double ask(int x){
double res = 0;
for(;x;x-=x&-x)res = max(res,c[x]);
return res;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
double r,h;
scanf("%lf%lf",&r,&h);
double vo = acos(-1) * r * r * h;
vol[i] = vo;
v.push_back(vo);
}
sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
double res = 0;
for(int i=1;i<=n;i++){
int x = getId(vol[i]);
double now = ask(x-1) + vol[i];
add(x,now);
res = max(res,now);
}
printf("%.10lf
",res);
return 0;
}
CF-332B
제목: 길이가 n인 서열을 정하고 두 단락이 교차하지 않는 길이가 k인 서열을 찾아 권한과 최대치를 설정합니다.
어떻게 하든지 할 수 있다. 사실 단조로운 대열과 같은 사상은 변수 하나만 보존하면 가장 좋은 결정을 내릴 수 있다
#include
using namespace std;
const int N = 200010;
typedef long long ll;
int n,k;
ll a[N],sum[N];
int main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
sum[i] = sum[i-1]+a[i];
}
int pre = 1,l = 1,r = k+1,fi = 1,se = 1;
ll res = 0;
for(;r<=n-k+1;r++){
if(sum[pre+k-1]-sum[pre-1] < sum[r-1]-sum[r-1-k])pre = r-k;
if(sum[r+k-1]-sum[r-1]+sum[pre+k-1]-sum[pre-1] > res){
res = sum[r+k-1]-sum[r-1]+sum[pre+k-1]-sum[pre-1];
fi = pre;
se = r;
}
}
printf("%d %d
",fi,se);
return 0;
}
CF-1043D
그리고 모든 상황은 원래의 기초 위에서 i개의 k를 더 추가할 수 있다.총 4*n종l
#include
using namespace std;
typedef long long ll;
ll n,k,a,b;
int main(){
cin>>n>>k>>a>>b;
ll mi = LONG_LONG_MAX;
ll mx = 0;
for(int i=0;i
CF-620 E - New Year Tree(상태 압축 + 세그먼트 트리)
#include
using namespace std;
const int N = 400010;
typedef long long ll;
int n,m,cnt,c[N],num[N],id[N];
ll color[N];
vector v[N];
void dfs(int x,int fa){
num[x] = 1;
color[++cnt] = 1ll<>1;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].data = t[p*2].data | t[p*2+1].data;
}
void spread(int p){
if(t[p].tag){
t[p*2].data = t[p].data;
t[p*2+1].data = t[p].data;
t[p*2].tag = 1;
t[p*2+1].tag = 1;
t[p].tag = 0;
}
}
void change(int p,int l,int r,int val){
if(t[p].l>=l&&t[p].r<=r){
t[p].data = 1ll<>1;
if(l<=mid)change(p*2,l,r,val);
if(r>mid)change(p*2+1,l,r,val);
t[p].data = t[p*2].data | t[p*2+1].data;
}
ll ask(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
return t[p].data;
}
spread(p);
int mid = t[p].l+t[p].r>>1;
ll res= 0;
if(mid>=l)res |= ask(p*2,l,r);
if(mid>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&c[i]);
for(int i=1;i<=n-1;i++){
int x,y;scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
dfs(1,-1);
build(1,1,n);
for(int i=1;i<=m;i++){
int k,x,y;
scanf("%d%d",&k,&x);
if(k==1){
scanf("%d",&y);
change(1,id[x],id[x]+num[x]-1,y);
}
else{
ll res = ask(1,id[x],id[x]+num[x]-1);
int ans = 0;
while(res){if(res&1)ans++;res/=2;}
printf("%d
",ans);
}
}
return 0;
}
CF-1140 E - Palindrome-less Arrays
제목: 채우지 않은 서열을 지정합니다. 수치가 -1이면 1~k의 숫자로 덮어쓸 수 있습니다. 이 서열을 채운 후 길이가 홀수인 회문열이 존재하지 않는 방안 수를 구하십시오.
분석:
i가 홀수인 경우 우리는 이 서열의 중간 위치인mid를 꺼낼 수 있다. -1열의 양쪽 숫자가 같고 모두 x와 같을 때mid숫자가 x와 같다고 가정하면 두 개의 길이가 i/2이고 서열의 양쪽 끝이 같은 서브문제로 전환한 다음에mid가 x와 다르다고 가정하면 (k-1)가지 방법이 있다. 똑같이 두 개의 길이가 i/2이고 서열의 양쪽 끝이 다른 서브문제로 전환할 수 있다.-1열의 양쪽 숫자가 같지 않으면 같은 이치이다.
d수 그룹을 미리 처리한 후에 우리가 이전에 나누었던 짝짓기를 처리할 수 있습니다.사고방식은 이전에 -1이 되지 않았던 위치를 기록하는 것이다.그리고 마지막으로 특판을 하면 정답을 얻을 수 있다.
#include
using namespace std;
typedef long long ll;
const int mod = 998244353;
ll d[100010][2];
int a[100010],b[100010];
ll n,k;
ll solve(int *a,ll len){
ll res = 1;
ll last = 0;
for(ll i=1;i<=len;i++){
if(a[i] == -1)continue;
else{
if(i == 1){
last = i;continue;
}
if(last == 0){
res = res * (d[i-2][0] + (k-1)*d[i-2][1])%mod;
}
else{
if(a[i] == a[last]){
res = res * d[i-last-1][0]%mod;
}
else res = res * d[i-last-1][1]%mod;
}
last = i;
}
}
if(last==0){
res = k;
for(int i=2;i<=len;i++)res = (res*(k-1))%mod;
}
else if(last !=len){
res = res * (d[len-last-1][0] + (k-1)*d[len-last-1][1]%mod)%mod;
}
return res;
}
int main(){
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++){
if(i&1)scanf("%d",&a[(i+1)/2]);
else scanf("%d",&b[i/2]);
}
d[0][0] = 0;d[0][1] = 1;
for(int i=1;i<=(n+1)/2;i++){
if(i&1){
int len = i/2;
d[i][0] = (d[len][0] * d[len][0]%mod + (k-1) * d[len][1]%mod * d[len][1]%mod)%mod;
d[i][1] = (d[len][0] * d[len][1]%mod * 2%mod + (k-2) * d[len][1]%mod * d[len][1]%mod)%mod;
}
else{
d[i][0] = (d[i-1][1] * (k-1)) % mod;
d[i][1] = (d[i-1][0] + (k-2) * d[i-1][1]%mod)%mod;
}
}
printf("%lld
",(solve(a,(n+1)/2)*solve(b,n-(n+1)/2))%mod);
return 0;
}
CH6101 최우선 무역(최단로)
#include
using namespace std;
const int N = 100010;
const int M = 500010;
int val[N],n,m,d[N],f[N],vis[N];
vector v[N];
struct edge{
int x,y,k;
}e[M];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&val[i]);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].k);
v[e[i].x].push_back(e[i].y);
if(e[i].k == 2)v[e[i].y].push_back(e[i].x);
}
memset(d,0x3f,sizeof d);
d[1] = val[1];
priority_queue< pair > q;
q.push(make_pair(-val[1],1));
while(!q.empty()){
int x = q.top().second;q.pop();
if(vis[x])continue;
vis[x] = 1;
for(int i=0;i min(val[y],d[x])){
d[y] = min(val[y],d[x]);
q.push(make_pair(-d[y],y));
}
}
}
for(int i=1;i<=n;i++){
v[i].clear();vis[i] = 0;
}
for(int i=1;i<=m;i++){
v[e[i].y].push_back(e[i].x);
if(e[i].k == 2)v[e[i].x].push_back(e[i].y);
}
q.push(make_pair(val[n],n));
f[n] = val[n];
while(!q.empty()){
int x = q.top().second;q.pop();
if(vis[x])continue;
vis[x] = 1;
for(int i=0;i
CF-1141F2 - Same Sum Blocks (Hard)
제목: 길이가 n(n<=1500)인 서열로 최대한 많은 구간으로 나누어 각 구간을 합친 것과 같다.
분석: 맵으로 각각 대응하는 구간의 좌우 단점
map>> segs;
을 저장한 다음에 동일한 화합에 대해 서로 교차하지 않는 구간을 최대 몇 개까지 나눌 수 있는지 확인해 본다.비교적 쉽게 생각할 수 있는 욕심 전략은 오른쪽 단점이 점차적으로 증가하는 순서대로 구간을 선택하는 것이다. 그러면 우리가 처음에 구간을 선별할 때 오른쪽 단점이 왼쪽에서 오른쪽으로 순서대로 하면 된다.#include
using namespace std;
int main(){
int n;
cin >> n;
vector a(n);
for (int i = 0; i < n; i++)
cin >> a[i];
map>> segs;
//
for (int r = 0; r < n; r++) {
int sum = 0;
for (int l = r; l >= 0; l--) {
sum += a[l];
segs[sum].push_back({l, r});
}
}
int result = 0;
vector> best;
for (const auto& p: segs) {
//const ,
const vector>& pp = p.second;
int cur = 0;
int r = -1;
//
vector> now;
for (auto seg: pp)
if (seg.first > r) {
cur++;
now.push_back(seg);
r = seg.second;
}
if (cur > result) {
result = cur;
best = now;
}
}
cout << result << endl;
for (auto seg: best)
cout << seg.first + 1 << " " << seg.second + 1 << endl;
return 0;
}
1119 D - Frets On Fire
사유문제, 어렵지 않은데 왜 겁먹었어.이런 난이도는 동메달 연습 문제도 계산하지 않을 것으로 추정된다.
#include
using namespace std;
const int N = 100010;
typedef unsigned long long ll;
ll s[N],n,q,c[N],sum[N];
int main(){
scanf("%lld",&n);
for(int i=0;i
1119 E - Pavel and Triangles
욕심이야, 지나칠 수 없는 욕심이 틀린 게 틀림없어. 우선 1+2의 일치 방안
#include
using namespace std;
const int N = 300010;
typedef long long ll;
ll a[N],n;
int main(){
scanf("%d",&n);
long long res = 0;
for (int i = 0; i < n; ++i)
{
scanf("%lld",&a[i]);
}
queue q;
ll last = 0;
ll now = 0;
for(int i=0;i
1139 E - Maximize Mex
마지막으로 그림을 만들고 이분도를 일치시킵니다.
#include
using namespace std;
const int N = 5050;
int n,m,p[N],c[N],d,del[N],res[N],k[N];
vector v[N];
int match[N],vis[N];
bool dfs(int x){
for(int i=0;i=1;i--){
int id = k[i];
for(;j<=5000;j++){
if(!dfs(j))break;// , Mex j
}
res[i] = j;
v[p[id]].push_back(c[id]);//
}
for(int i=1;i<=d;i++)
printf("%d
",res[i]);
return 0;
}
결어:
최근에 물 문제를 좀 풀었죠. 별로 나아진 게 없는 것 같아서 사유량이 있는 문제를 만나면 오버를 해요.어제 시합을 했는데 자폐를 했습니다. 그래서 2주 동안 밀린 기록을 보충했습니다. 사실 평소에도 썼는데 어수선할 뿐입니다. 최근 2주 동안 두 번째 푸른 책을 보고 있습니다.여름 방학 전에 정해진 내용을 다 보내야 해요.힘을 내다
전재 대상:https://www.cnblogs.com/1625--H/p/10706010.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.