首页 > 其他分享 >分治专题

分治专题

时间:2023-07-02 21:44:32浏览次数:31  
标签:专题 cntb cnta int 分治 mid include dp

在牛子老师的博客下边看到 yspm 给了 CF1019E。看了一眼,不会。看了题解,我超边分治 + 闵可夫斯基和,一个都不会。乐。

还有 20 天,还能补多少坑呢,不好说。

仍然是每天高压作业。但是出乎意料的晚上不是很失眠,虽然说醒了以后还是很困。

现象:让大象出现的事物或者方法。大象是一种体量很大、包容万物的生物,平时喜欢躲在泥土下面拿长长的鼻子冒充仙人掌以攫食长颈鹿。因为大象的鼻子看起来像是罕见的仙人掌,很多人希望能将新奇的仙人掌品种给引入园艺界。此时大象就会拔地而起,狠揍植物猎人并把植物猎人挂在树梢上当做大雁发表演说用的讲台。

同理可定义抽象:一种让大象出现的方法。即用真空泵将大象从地下抽出。

P6932 [ICPC2017 WF] Money for Nothing

洛谷题面翻译什么寄吧。题意是每一天都能倒卖一次,但是自始至终只能和一对交易。也就是左下角卖家右上角买家的矩形最大面积。

首先可能成为答案的点肯定是从左上到右下一排。然后固定左下的点,右上的点的选取有单调性,于是可以按着决策单调性的分治写法直接冲。

忘了怎么写了,贺了一发。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#define int long long
using namespace std;
int n,m,ans,cnta,cntb;
struct node{
    int x,y;
    bool operator<(const node&s)const{
        return x==s.x?y<s.y:x<s.x;
    }
}a[500010],b[500010],tmp[500010];
void solve(int l,int r,int L,int R){
    if(l>r||L>R)return;
    int mid=(l+r)>>1,pos=0,val=-0x3f3f3f3f3f3f3f3f;
    for(int i=L;i<=R;i++){
        if(a[mid].x<b[i].x||a[mid].y<b[i].y){
            int ret=(b[i].x-a[mid].x)*(b[i].y-a[mid].y);
            if(ret>val)val=ret,pos=i;
        }
    }
    ans=max(ans,val);
    if(pos){
        solve(l,mid-1,L,pos);solve(mid+1,r,pos,R);
    }
}
signed main(){
    scanf("%lld%lld",&m,&n);
    for(int i=1;i<=m;i++)scanf("%lld%lld",&tmp[i].x,&tmp[i].y);
    sort(tmp+1,tmp+m+1);a[0].y=0x3f3f3f3f3f3f3f3f;
    for(int i=1;i<=m;i++){
        if(a[cnta].y>tmp[i].y)a[++cnta]=tmp[i];
    }
    for(int i=1;i<=n;i++)scanf("%lld%lld",&tmp[i].x,&tmp[i].y);
    sort(tmp+1,tmp+n+1);
    for(int i=1;i<=n;i++){
        while(cntb&&b[cntb].y<tmp[i].y)cntb--;
        b[++cntb]=tmp[i];
    }
    solve(1,cnta,1,cntb);
    printf("%lld\n",ans);
    return 0;
}

gym103202L Forged in the Barrens

十分奇妙。

首先看上去就有个最大流建模。模拟最大流大概也能过。但我们不这么干,因为有点丑陋。

每个区间一头的贡献是 \(+1\),一头是 \(-1\)。那么考虑一个 dp:设 \(dp_{0/1/2,0/1/2,l,r,x}\) 为区间 \([l,r]\) 选了 \(x\) 段,左右没有东西 / 空了一段正贡献 / 负贡献。则转移考虑分治,有:

\[dp_{s_l,s_r,l,r,x}=\max(\max_{x_1+x_2=x}dp_{s_l,0,l,mid,x_1}+dp_{0,s_r,mid+1,r,x_2},\\ \max_{x_1+x_2+1=x}dp_{s_l,1,l,mid,x_1}+dp_{2,s_r,mid+1,r,x_2},\\ \max_{x_1+x_2+1=x}dp_{s_l,2,l,mid,x_1}+dp_{1,s_r,mid+1,r,x_2},\\ dp_{s_l,s_r,l,mid,x},dp_{s_l,s_r,mid+1,r,x})\]

发现这玩意关于 \(x\) 是凸的,于是直接闵可夫斯基和合并凸包。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
#define int long long
int n,a[200010];
const int inf=0x3f3f3f3f3f3f3f3f;
struct node{
    vector<int>v[3][3];
};
vector<int>Merge(vector<int>a,vector<int>b){
    for(int i=a.size()-1;i>=1;i--)a[i]-=a[i-1];
    for(int i=b.size()-1;i>=1;i--)b[i]-=b[i-1];
    vector<int>c(a.size()+b.size()-1);
    c[0]=a[0]+b[0];
    merge(a.begin()+1,a.end(),b.begin()+1,b.end(),c.begin()+1,greater<int>());
    for(int i=1;i<a.size()+b.size()-1;i++)c[i]+=c[i-1];
    return c;
}
vector<int>max(vector<int>a,vector<int>b){
    int n=max(a.size(),b.size());
    while(a.size()<n)a.push_back(-inf);
    while(b.size()<n)b.push_back(-inf);
    for(int i=0;i<n;i++)a[i]=max(a[i],b[i]);
    return a;
}
node solve(int l,int r){
    if(l==r){
        node ans;
        ans.v[0][0].push_back(0);ans.v[0][0].push_back(0);
        ans.v[1][0].push_back(-inf);ans.v[1][0].push_back(a[l]);
        ans.v[2][0].push_back(-a[l]);
        ans.v[0][1].push_back(-inf);ans.v[0][1].push_back(a[l]);
        ans.v[1][1].push_back(-inf);
        ans.v[2][1].push_back(-inf);
        ans.v[0][2].push_back(-a[l]);
        ans.v[1][2].push_back(-inf);
        ans.v[2][2].push_back(-inf);
        return ans;
    }
    int mid=(l+r)>>1;
    node L=solve(l,mid),R=solve(mid+1,r),ans;
    for(int l=0;l<3;l++){
        for(int r=0;r<3;r++){
            ans.v[l][r]=max(max(Merge(L.v[l][0],R.v[0][r]),Merge(L.v[l][1],R.v[2][r])),max(Merge(L.v[l][2],R.v[1][r]),max(L.v[l][r],R.v[l][r])));
        }
    }
    return ans;
}
signed main(){
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)scanf("%lld",&a[i]);
    node ans=solve(1,n);
    for(int i=1;i<=n;i++)printf("%lld\n",ans.v[0][0][i]);
    return 0;
}

uoj#592. 新年的聚会

比较神奇。

考虑随机打乱所有点,然后维护若干个独立集。每次找一个 \(x\),对每个独立集分治找到和它们连的所有边,然后加入最小的独立集里边。复杂度不会证明。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <random>
#include <ctime>
#include <vector>
#include "meeting.h"
using namespace std;
int n,m,cnt,id[1010];
vector<pair<int,int> >ans;
vector<int>v[2010];
mt19937 rnd(time(0)^(unsigned long long)(new char));
bool check(int pos,int x,int l,int r){
    vector<int>ret;ret.push_back(x);
    for(int i=l;i<=r;i++)ret.push_back(v[pos][i]);
    return meeting(ret);
}
bool solve(int pos,int x,int l,int r,bool jud){
    if(l>r)return false;
    if(!jud&&check(pos,x,l,r))return false;
    if(l==r){
        ans.push_back(make_pair(x,v[pos][l]));
        return true;
    }
    int mid=(l+r)>>1;
    if(!check(pos,x,l,mid)){
        solve(pos,x,l,mid,true);solve(pos,x,mid+1,r,false);
    }
    else solve(pos,x,mid+1,r,true);
    return true;
}
vector<pair<int,int> >solve(int n){
    for(int i=0;i<n;i++)id[i]=i;
    shuffle(id,id+n,rnd);
    for(int i=0;i<n;i++){
        int x=id[i],pos=-1;
        for(int j=1;j<=cnt;j++){
            if(!solve(j,x,0,v[j].size()-1,false)){
                if(pos==-1||v[j].size()<v[pos].size())pos=j;
            }
        }
        if(pos==-1)pos=++cnt;
        v[pos].push_back(x);
    }
    return ans;
}

CF1442D Sum

大结论题。

结论是过程中最多只有一个序列被选了一部分。

证明:反证,假设有两个序列 \(a,b\) 选到了 \(a_x,b_y\),其中 \(a_x\ge b_y\),那么选到 \(a_{x+1},b_{y-1}\) 一定更优。

于是就相当于做一个强制某个元素不选的背包,直接分治就好了。

轻微卡常(也可能是我实现有问题),每个分治节点开个 dp 会 T。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector>
#define int long long
using namespace std;
int n,k,ans,sum[3010],cnt[3010],dp[3010][21];
vector<int>a[3010];
void solve(int l,int r,int dep){
    if(l==r){
        int sum=0,cnt=0;
        ans=max(ans,dp[k][dep]);
        for(int x:a[l]){
            cnt++;sum+=x;
            if(cnt>k)break;
            ans=max(ans,dp[k-cnt][dep]+sum);
        }
        return;
    }
    int mid=(l+r)>>1;
    for(int i=0;i<=k;i++)dp[i][dep+1]=dp[i][dep];
    for(int i=mid+1;i<=r;i++){
        for(int j=k;j>=cnt[i];j--)dp[j][dep+1]=max(dp[j][dep+1],dp[j-cnt[i]][dep+1]+sum[i]);
    }
    solve(l,mid,dep+1);
    for(int i=0;i<=k;i++)dp[i][dep+1]=dp[i][dep];
    for(int i=l;i<=mid;i++){
        for(int j=k;j>=cnt[i];j--)dp[j][dep+1]=max(dp[j][dep+1],dp[j-cnt[i]][dep+1]+sum[i]);
    }
    solve(mid+1,r,dep+1);
}
signed main(){
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%lld",&cnt[i]);
        for(int j=1;j<=cnt[i];j++){
            int x;scanf("%lld",&x);a[i].push_back(x);sum[i]+=x;
        }
    }
    for(int i=1;i<=k;i++)dp[i][0]=-0x3f3f3f3f3f3f3f3f;
    solve(1,n,0);
    printf("%lld\n",ans);
    return 0;
}

CF1553H XOR and Distance

参考 x义x 老师的神秘解法。

设 \(dp_{x,d}\) 为强制 \(x\) 使用和 \(x\) 相比只有低 \(d\) 位不同的元素的答案,\(mn{x,d}\) 为它们和 \(x\) 异或最小值,\(mx_{x,d}\) 为最大值。

考虑转移到 \(d+1\)。\(mn,mx\) 的转移比较显然:设 \(x,y\) 满足 \(y=x+2^d\),则

\[mn_{x,d+1}=\min(mn_{x,d},mn_{y,d}+2^d) \]

\(mx\) 的式子是一样的。那么考虑转移 \(dp\)。元素对有三类:

  1. 都在 \((x,d)\) 中:就是 \(dp_{x,d}\)。
  2. 都在 \((y,d)\) 中:就是 \(dp_{y,d}\)。
  3. 两个都在:这个可以发现是 \(mn_{x,d}-mx_{y,d}+2^d\)。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,k,dp[1<<19],mx[1<<19],mn[1<<19];
int main(){
    scanf("%d%d",&n,&k);
    memset(dp,0x3f,sizeof(dp));memset(mn,0x3f,sizeof(mn));memset(mx,-0x3f,sizeof(mx));
    for(int i=1;i<=n;i++){
        int x;scanf("%d",&x);
        mx[x]=mn[x]=0;
    }
    for(int i=0;i<k;i++){
        for(int s=0;s<(1<<k);s++){
            if(!((s>>i)&1))continue;
            dp[s^(1<<i)]=dp[s]=min(dp[s^(1<<i)],dp[s]);
            dp[s^(1<<i)]=min(dp[s^(1<<i)],mn[s]-mx[s^(1<<i)]+(1<<i));
            dp[s]=min(dp[s],mn[s^(1<<i)]-mx[s]+(1<<i));
            int mn1=mn[s^(1<<i)],mn2=mn[s],mx1=mx[s^(1<<i)],mx2=mx[s];
            mn[s^(1<<i)]=min(mn[s^(1<<i)],mn2+(1<<i));
            mn[s]=min(mn[s],mn1+(1<<i));
            mx[s^(1<<i)]=max(mx[s^(1<<i)],mx2+(1<<i));
            mx[s]=max(mx[s],mx1+(1<<i));
        }
    }
    for(int i=0;i<(1<<k);i++)printf("%d ",dp[i]);puts("");
    return 0;
}

CF1179E Alesya and Discrete Math

这分治题单是没有贪心是吧。

首先都分治题单了肯定要分治是不是。于是考虑分治:找到每个函数取值为 \(\dfrac L2\) 的位置,然后排序,找到中间的一个,分到左右两半为子问题。询问次数 \(n\log n\log L\),过不去。

分治不好去掉,但是似乎没必要询问每个的值,只要找到最中间的一个函数是谁就行了。随机一个函数检查,然后每次在多的那一半里边重复该过程,那么期望 \(O(\log n)\) 次找到。这样单层的询问次数就从 \(O(n\log L)\) 变成了 \(\sum\log n\log L\),总复杂度是 \(\sum_{i=1}^{\log n}i2^{\log n-i}\log L=O(n\log L)\),可以通过。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define int long long
using namespace std;
int n,L;
pair<int,int>ans[1010];
int query(int id,int x){
    printf("? %lld %lld\n",id,x);
    fflush(stdout);
    scanf("%lld",&x);
    return x;
}
int getpos(int l,int r,int val,int id){
    while(l<r){
        int mid=(l+r)>>1;
        if(query(id,mid)>=val)r=mid;
        else l=mid+1;
    }
    return l;
}
int find(int l,int r,int val,int cnt,vector<int>v){
    int pos=v[rand()%v.size()];
    int p=getpos(l,r,val,pos);
    vector<int>L,R,ret;ret.push_back(pos);
    for(int x:v){
        if(x==pos)continue;
        int tmp=query(x,p);
        if(tmp<val)R.push_back(x);
        if(tmp>val)L.push_back(x);
        if(tmp==val)ret.push_back(x);
    }
    while(!ret.empty()&&L.size()<cnt)L.push_back(ret.back()),ret.pop_back();
    while(!ret.empty())R.push_back(ret.back()),ret.pop_back();
    if(L.size()==cnt)return p;
    if(L.size()>cnt)return find(l,r,val,cnt,L);
    else return find(l,r,val,cnt-L.size(),R);
}
void solve(int l,int r,int L,int R,vector<int> v){
    if(v.empty())return;
    if(v.size()==1){
        ans[v[0]].first=L,ans[v[0]].second=R;
        return;
    }
    int mid=l+(r-l)/v.size()*(v.size()>>1);
    int pos=find(L,R,mid,v.size()>>1,v);
    vector<int>ll,rr,ret;
    for(int x:v){
        int tmp=query(x,pos);
        if(tmp>mid)ll.push_back(x);
        if(tmp<mid)rr.push_back(x);
        if(tmp==mid)ret.push_back(x);
    }
    while(!ret.empty()&&ll.size()<(v.size()>>1))ll.push_back(ret.back()),ret.pop_back();
    while(!ret.empty())rr.push_back(ret.back()),ret.pop_back();
    solve(l,mid,L,pos,ll);
    solve(mid,r,pos,R,rr);
}
signed main(){
    scanf("%lld%lld",&n,&L);
    vector<int>v;
    for(int i=1;i<=n;i++)v.push_back(i);
    solve(0,L,0,1e18,v);
    puts("!");
    for(int i=1;i<=n;i++)printf("%lld %lld\n",ans[i].first,ans[i].second);
    return 0;
}

CF865F Egg Roulette

官方题解没看懂。

首先有个神秘结论:对于任意包含不超过 \(R-1\) 个 \(A\) 或 \(B\) 的前缀可以随意重排而不改变不公平度。官方题解说因为该赢的不会输该输的不会赢。感觉很感性。称这样的前缀是合法的。

然后既然这样了就有个比较显然的东西:任意序列都可以提 \(R-1\) 个 \(A\) 和 \(R-1\) 个 \(B\) 放开头而不改变不公平度。

考虑先算出来不公平度,这一点通过不断往最后边塞操作,直到塞到一个合法前缀来得到。首先两个人的操作数是相等的,然后若现在 Alice 有 \(cnta\) 个操作,Bob 有 \(cntb\) 个操作,则若 Alice 往最后边放一个,Bob 增加的胜场数是 Alice 往最后放一个 R 的方案,即 \(\dbinom{cnta-1}{R-1}\dbinom{cntb}R\)。

这部分的复杂度是 \(2^{2C}\) 的,但是可以加个剪枝:先找到一个足够小的不公平度,然后通过最优化剪枝减小状态数。这个可以通过哪边小补哪里的贪心方式填出一个不公平度。

然后是统计答案。同样往最后边塞操作,当塞到一个合法前缀的时候统计答案。假设这时有 \(cnta\) 个 \(A\),\(cntb\) 个 \(B\),而这个前缀有 \(a\) 个确定的 \(A\),\(b\) 个确定的 \(B\),那方案数显然是 \(\dbinom{cnta-a+cntb-b}{cnta-a}\)。记搜即可通过。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#define int long long
using namespace std;
int n,m,ans,C[70][70],suma[70],sumb[70];
char s[70];
void dfs(int x,int y,int cnta,int cntb){
    if(ans<=1||abs(x-y)-C[cnta][n]*C[cntb][n]>ans)return;
    if(cnta<n||cntb<n){
        ans=min(ans,abs(x-y));return;
    }
    if(cnta>=n)dfs(x,y+C[cnta-1][n-1]*C[cntb][n],cnta-1,cntb);
    if(cntb>=n)dfs(x+C[cntb-1][n-1]*C[cnta][n],y,cnta,cntb-1);
}
map<int,int>mp[70][70];
int solve(int x,int y,int cnta,int cntb){
    if(mp[cnta][cntb].find(x-y)!=mp[cnta][cntb].end())return mp[cnta][cntb][x-y];
    if(abs(x-y)-C[cnta][n]*C[cntb][n]>ans)return mp[cnta][cntb][x-y]=0;
    if(cnta<n||cntb<n){
        if(cnta>=suma[cnta+cntb]&&cntb>=sumb[cnta+cntb])return mp[cnta][cntb][x-y]=C[cnta+cntb-suma[cnta+cntb]-sumb[cnta+cntb]][cnta-suma[cnta+cntb]];
        else return mp[cnta][cntb][x-y]=0;
    }
    int ans=0;
    if(s[cnta+cntb]!='B')ans+=solve(x,y+C[cnta-1][n-1]*C[cntb][n],cnta-1,cntb);
    if(s[cnta+cntb]!='A')ans+=solve(x+C[cntb-1][n-1]*C[cnta][n],y,cnta,cntb-1);
    return mp[cnta][cntb][x-y]=ans;
}
signed main(){
    scanf("%lld%lld%s",&n,&m,s+1);
    for(int i=0;i<=(n+m<<1);i++){
        C[i][0]=1;
        for(int j=1;j<=i;j++)C[i][j]=C[i-1][j-1]+C[i-1][j];
    }
    int x=0,y=0,cnta=n+m,cntb=n+m;
    while(cnta>=n&&cntb>=n){
        if(x>y)y+=C[cnta-1][n-1]*C[cntb][n],cnta--;
        else x+=C[cntb-1][n-1]*C[cnta][n],cntb--;
    }
    ans=abs(x-y);
    dfs(0,0,n+m,n+m);
    for(int i=1;i<=(n+m<<1);i++){
        suma[i]=suma[i-1]+(s[i]=='A');
        sumb[i]=sumb[i-1]+(s[i]=='B');
    }
    printf("%lld\n",solve(0,0,n+m,n+m));
    return 0;
}

标签:专题,cntb,cnta,int,分治,mid,include,dp
From: https://www.cnblogs.com/gtm1514/p/17521480.html

相关文章

  • 最强优化指令大全 | 【Linux技术专题】「系统性能调优实战」终极关注应用系统性能调优
    Linux命令相关查看指标CPU指标vmstat指令vmstat-nm该命令用于每隔n秒采集系统的性能统计信息,共采集m次。[root@svr01]$vmstat13procs-----------memory-------------swap-------io------system-------cpu-----rbswpdfreebuffcachesiso......
  • 【杂题乱写】6 月多校分治专题训练
    AGym-101471DMoneyfornothing就是求\((d_j-c_i)(q_j-p_i)\)的最大值。可以看作点对\((d_j,q_j)\)与\((c_i,p_i)\)在二维平面上构成矩形的最大值,且\(c_i\ged_j,p_i\geq_j\)。把卖家点对放在序列\(a\),买家点对放在序列\(b\),先删去一定不优的点,删完之后\(a,b\)都......
  • 【杂题乱写】6 月多校分治专题训练
    AGym-101471DMoneyfornothing就是求\((d_j-c_i)(q_j-p_i)\)的最大值。可以看作点对\((d_j,q_j)\)与\((c_i,p_i)\)在二维平面上构成矩形的最大值,且\(c_i\ged_j,p_i\geq_j\)。把卖家点对放在序列\(a\),买家点对放在序列\(b\),先删去一定不优的点,删完之后\(a,b\)都......
  • 【杂题乱写】6 月多校分治专题训练
    AGym-101471DMoneyfornothing就是求\((d_j-c_i)(q_j-p_i)\)的最大值。可以看作点对\((d_j,q_j)\)与\((c_i,p_i)\)在二维平面上构成矩形的最大值,且\(c_i\ged_j,p_i\geq_j\)。把卖家点对放在序列\(a\),买家点对放在序列\(b\),先删去一定不优的点,删完之后\(a,b\)都......
  • 「学习笔记」CDQ分治
    CDQ分治的思想最早由IOI2008金牌得主陈丹琦在高中时整理并总结,目前这个思想的拓展十分广泛。优点:可以将数据结构或者DP优化掉一维缺点:这是离线算法。引入让我们来看一个问题有$n$个元素,第$i$个元素有$a_i,b_i,c_i$三个属性,设$f(i)$表示满足$a_j\l......
  • 【深入了解系统性能优化】「实战技术专题」全方面带你透彻探索服务优化技术方案(系统服
    调优意义系统运行缓慢,执行速度较差虽然没有对用户或公司造成实质性的损失,但它从侧面反映出系统在某些方面存在问题。可能需要对系统参数进行优化,或者对系统的设计和交互进行调整,这是后续系统性能优化的一个重要过程。我们将继续努力优化系统,以确保其高效运行和良好性能,以提升用户体......
  • 【深入了解系统性能优化】「实战技术专题」全方面带你透彻探索服务优化技术方案(系统服
    @目录调优意义计划分析流程相关分析优化分析Nginx请求服务日志将请求热度最高的接口进行优化异步调用优化方式注意要点分析调用链路追踪体系建立切面操作分析性能和数据统计存储相关的调用以及耗时信息分析信息以及相关的耗时损耗日志系统的升级和优化异步日志处理机制异常问题和......
  • 【分布式技术专题】「分布式技术架构」实践见真知,手把手教你如何实现一个属于自己的RP
    RPC是什么RPC(RemoteProcedureCall,远程过程调用)是一种计算机通信协议,它允许一个程序调用另一个程序所在的远程计算机上的子程序(或函数)而不需要自己的代码去处理远程调用的细节。RPC的应用RPC技术应用广泛,特别是在分布式系统中。比如,在Web开发中,有时需要从后端服务器请求数据,此时......
  • [刷题记录Day1]Leetcode列表专题
    No.1题目二分查找思路要素:原数组升序排列清楚地定义左右边界优化空间:数组有序,通过第0元素和最后元素,可以避免查找不在数组范围内的target代码publicstaticintsearch(int[]nums,inttarget){//避免target小于nums[0],大于nums[nums.length-1]时参与运算......
  • [刷题记录Day3]Leetcode链表专题
    #ListNodedefinitionpublicclassListNode{//结点的值intval;//下一个结点ListNodenext;//节点的构造函数(无参)publicListNode(){}//节点的构造函数(有一个参数)publicListNode(intval){this.val=val;......